1

I have a program with two external files in addition to main.cpp and a header of constants. So in total four files. They contain the following code:

main.cpp

#include <iostream> using namespace std; int ext1_func(); int ext2_func(); int main() { int i; i = ext1_func(); cout << i << endl; i = ext2_func(); cout << i << endl; return 0; } 

ext1.cpp

#include "const.h" int asd1=1; int ext1_func() { return temp_int; } 

ext2.cpp

#include "const.h" int asd2 = 2; int ext2_func() { return temp_int; } 

const.h

#ifndef CONST_H #define CONST_H const int temp_int=1; #endif 

My desired is the following:

1) Any variables declared in ext1.cpp should be known only to functions within ext1.cpp and likewise for ext2.cpp. So "asd1" must only be known to "ext1_func" and "asd2" for "ext2_func".

2) The functions in "exp1.cpp" and "ext2.cpp" must be able to see all values defines in "const.h"

I believe that the code I have written and attached satisfies these requirements, but I would like to ask if I am doing it correctly? Is there an easier way to obtain the desired behavior than what I have suggested?

Thanks in advance.

Niles.

1
  • The biggest problems with the code shown are (1) the asdN variables are visible outside their source files (discussed in extenso in the various answers), and (2) there isn't a header declaring the functions that is used to enforce consistency between the code using the functions (main.cpp) and the code defining the functions (extN.cpp). Granted, C++ has type-safe linkage (unlike C, where I mainly work). However, in general, it is best not to write extern declarations in source files — there should be a header that declares the functions that is used to enforce consistency. Commented Oct 18, 2012 at 12:56

4 Answers 4

2

Within compilation unit level, the symbols you declare at "global" scope are all linked in to the global variable space.

The old way to avoid this was to declare them static. The new way is to put them into an anonymous namespace. They can also be declared static there too.

ext1.cpp

namespace { /*static*/ int asd1=1; } 

The const in the header is ok, constants declared this way have a special status, in fact that compiler can substitute in the code the value. Ideally though, you should at least wrap them in a (named) namespace to avoid polluting the global one. Modifying the value (using const_cast) would be undefined behaviour.

If it were non-const and you really wanted a global (not generally a good idea) you would need to use the extern keyword in the header, then create its instance in a single compilation unit.

Sign up to request clarification or add additional context in comments.

2 Comments

Regarding "The const in the header is ok, [...]", thanks for that. I was worried that it was poor programming style to define global constants in this way, now I'll just keep it as it is.
global constants are ok, but ideally you should put them into a (named) namespace so as not to "pollute" the global namespace.
2

Instead of repeating ext1_func() and ext2_func() prototypes in main.cpp, I'd define an header file for each function, and add function prototypes there:

// ext1.h #ifndef EXT1_H_INCLUDED #define EXT1_H_INCLUDED int ext1_func(); #endif // EXT1_H_INCLUDED // ext2.h #ifndef EXT2_H_INCLUDED #define EXT2_H_INCLUDED int ext2_func(); #endif // EXT2_H_INCLUDED 

In main.cpp:

#include "ext1.h" #include "ext2.h" 

In ext1.cpp and ext2.cpp, use anonymous namespaces for variables local only to the source file:

// ext1.cpp #include "const.h" #include "ext1.h" namespace { int asd1=1; } // anonymous namespace int ext1_func() { return temp_int; } 

Similar for ext_2.cpp.

You may also want to use the convenient #pragma once in header files, instead of #ifndef/#define include guards.

2 Comments

what is the advantage of adding the definition in "const.cpp" instead of my approach where I do it all in "const.h"?
@niles_1710373: For a discussion on defining constants in headers or not, see AndreyT's answer.
1

You should define the variables in ext1.cpp and ext2.cpp to be static to prevent them from being seen by other files. But, this is a very bad way of building things. You should instead separate your code into different classes. See this for details.

2 Comments

I disagree with you in general that "you should separate your code into different classes". It maybe that there should be classes and objects but C++ does not in general support the "everything must be in a class" paradigm.
-1 for pointing to the highly abstract Wikipedia page about OOP "for details". Besides, C++ doesn't support things like anonymous namespaces for no reason, and the current program is far too trivial to warrant an OO design.
1

When you want to make variable local to the translation unit (.cpp file) you put them into an anonymous namespace like this:

namespace { int local_variable = 1; } 

Alternative you can also do it the old C way:

static int local_variable = 1; 

Also you should not be defining variables in the header files, because it will duplicated in every .cpp module where this header file is included. You should declare it as external like this in const.h:

extern int external_variable; 

And then in the corresponding const.cpp file define it like this:

int external_variable = 1; 

2 Comments

Thanks! But is it OK to define a constant variable in "const.h"? Will it still be duplicated in every module?
@niles_1710373, for const int and other integral types it's ok.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.