# Confused about constants defined in namespaces

## Recommended Posts

Hi, I used to operate under the assumption that in C++, constants defined in a header file ... like so
// Constants.h
namespace Constants
{
const int theInt = 6;
}


would be shared by all compilation units including this header. That is, instead of each compilation unit getting its own copy of theInt, all compilation units including Constants.h would share one copy of theInt. However, I just compiled a minimal project (Visual C++ 2005) that has 2 compilation units CompilationUnit1.cpp and CompilationUnit2.cpp that both pull in Constants.h and then print the address of Constants::theInt, and surprisingly the addresses did not match! :o What do I need to do if I want all compilation units to share the same instance of Constants::theInt?

##### Share on other sites
Hmm, apparently if I declare theInt 'extern' and then initialize it in a separate cpp (Constants.cpp), all compilation units really get to share the same copy of theInt. Is that the recommended way of sharing constants across compilation units?

Yes it is!

##### Share on other sites
Quote:
 Original post by Red AntIs that the recommended way of sharing constants across compilation units?

The recommended way for integral constants is to refrain from taking their addresses, then they don't even consume any memory in the first place (in most cases).

##### Share on other sites
Quote:
 Original post by DevFredThe recommended way for integral constants is to refrain from taking their addresses, then they don't even consume any memory in the first place (in most cases).

Ah okay, so I can continue just declaring my constants like this

// constants.hnamespace Constants{    const int a = 4444;    const bool x = true;}

and then pull in constants.h where ever I need to access them? I was just worrying that I'd unnecessarily increase my memory footprint by having each compilation unit use its own copy of each constant.

##### Share on other sites
Quote:
Original post by DevFred
Quote:
 Original post by Red AntIs that the recommended way of sharing constants across compilation units?

The recommended way for integral constants is to refrain from taking their addresses, then they don't even consume any memory in the first place (in most cases).

Even better: Use an enum.

// Constants.hnamespace Constants{    enum { theInt = 6 };}

Now it is even forbidden to take the address, and you are guaranteed that this is a pure compile time construct. No need to kludge with extern or static keywords.

##### Share on other sites
Quote:
 Original post by phresnelEven better: Use an enum.

I do where ever possible but sometimes you need a const double, bool or whatever.

##### Share on other sites
Quote:
 Original post by Red AntI do where ever possible but sometimes you need a const double, bool or whatever.

Bool will also work:
enum { is_little_endian = true };

But you are right about non integral types. The only "hardened" solution that comes to mind is to use #define macros, but that I'd avoid (just alone because of scoping issues). For my code, const-float duplication is not so relevant, so I just sticked to static const floats and doubles.

If duplication is an issue, then of course make them extern, and put the definitions into a file named "constants.[cpp|cc|cxx|etc.]" or give it a finer grained name like "planet-size-constants.[...]".

edit: typo

[Edited by - phresnel on March 12, 2009 7:54:40 AM]

##### Share on other sites
Quote:
 Original post by Red AntI was just worrying that I'd unnecessarily increase my memory footprint by having each compilation unit use its own copy of each constant.

This doesn't happen because in general (what DevFred was alluding to) the constant will simply be inlined at each point of usage when possible, and then the static constant value will be recognized as a "dead" value and optimized out of the binary. But as soon as you try to take the address of the constant, it has to exist so that it can have an address, and won't be optimized out.

##### Share on other sites
Minor Addition: If you have static const member variables of type float, you have to implant them in some translation unit. Just happened to me this morning, when I added a generic version of an epsilon- and an infinity- constant.

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627689
• Total Posts
2978648

• 13
• 14
• 12
• 10
• 12