2

I have a global unique value, which I wish to use it across within a exe and different DLLs.

For any project which wish to use it, they may just include defs.h

I was wondering, should I declare it as

// defs.h
const UINT UNIQUE_MESSAGE = 
    RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

OR

// defs.h
const static UINT UNIQUE_MESSAGE = 
    RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

Currently, I do not find any different from code consumer point of view. Is there any catch behind? Should I use static or not?

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • 1
    My intuition is that with `static`, every translation unit will have its own instance of `UNIQUE_MESSAGE` but I'm not sure at all. – ereOn Apr 26 '11 at 07:55

3 Answers3

8

In C++, namespace level const are implicitly static (i.e it has internal linkage), unless you write extern const. So both of your syntax is basically same.

§7.1.1/6 says,

Objects declared const and not explicitly declared extern have internal linkage.

So I would suggest this: (with minimal consideration, like excluding static initialization order fiasco and many other issues with static and global variables)

//in defs.h:
extern const UINT UNIQUE_MESSAGE;

//defs.cpp
const UINT UNIQUE_MESSAGE =  RegisterWindowMessage(_T("whatever"));
Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Really? So to use a const in C++ in multiple compilation units you need to declare it extern? That sounds really strange to me, but maybe I'm just doing too much C coding lately ;-) – Robert S. Barnes Apr 26 '11 at 07:58
  • 1
    @Nawaz I dissagree with you when you're saying that const are static by dflt. They aren't. If you don't believe me try this: class X { public: static int vs; const int vc; X():vc(1){} }; int X::vs = 0; int main() { cout << X::vc << '\n'; cout << X::vs << '\n'; return 0; } – There is nothing we can do Apr 26 '11 at 08:03
  • @Robert: This behaviour is exactly the same as in plain c – chrmue Apr 26 '11 at 08:04
  • @There is nothing we can do: Its **at namespace level, not at class level scope**. I edited my post so as to avoid any misconception. – Nawaz Apr 26 '11 at 08:06
  • @Nawaz and Yan the point is that static and const both have internal linkage and this is the crux; – There is nothing we can do Apr 26 '11 at 08:10
  • @There is nothing we can do: Yeah. So? Am I saying anything different? – Nawaz Apr 26 '11 at 08:12
  • The suggested solution isn't convenient. If I have several DLL projects, I need to perform external linkage through lib, in order to get the definition. If I have the definition in header file, it can be as easy as just a simple include. – Cheok Yan Cheng Apr 26 '11 at 08:41
  • @Yan Cheng CHEOK: The suggested solution is with minimal consideration, and so with minimal changes. One might come and can still talk about thread issues, static initialization order fiasco and so on. – Nawaz Apr 26 '11 at 08:49
  • @chrmue: I just spent some time looking through both K&R and the c99 spec and couldn't find anything which seemed to imply that `const` qualified variables have implicit `static` / internal linkage. – Robert S. Barnes Apr 26 '11 at 17:47
  • @Robert: I said it's in C++. Not in C. – Nawaz Apr 26 '11 at 17:49
  • 1
    @Nawaz: That's why my comment was directed to chrmue and not you ;-) – Robert S. Barnes Apr 27 '11 at 08:16
  • @There is nothing we can do: Yeah. So? Am I saying anything different? Nawaz. In reply to that: The point is that before you extensively edited your answer into unrecognizable form to your original answer it is that you didn't mention a word about linking. That's all. – There is nothing we can do Apr 27 '11 at 09:51
  • @There is nothing we can do: At the namespace level, saying something is implicitly `static` is equivalent to saying "it has internal linkage". My edit is for people who do **not** understand this equivalence. – Nawaz Apr 27 '11 at 09:54
1

Every CPP file that includes defs.h will have its own instance of the const in memory. If you want to have only one instance in memory you have to declare it once in a cpp file like you did it:

const UINT UNIQUE_MESSAGE = RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

In the def.h you have to reference the const as an external:

extern const UINT UNIQUE_MESSAGE;

chrmue
  • 1,552
  • 2
  • 18
  • 35
0

If the example you give is correct then I would be concerned with the fact that your header file re-declares and initializes this value for each file it is included in. If declared in more than one file without namespaces you will end up with multiple declarations of the same symbol.

Furthermore even if this was just a declaration and the implementation was in a separate source file there are many noted problems with static globals including the initialization order of non-local static globals (initializer of one global in one file depending on another global in a separate file being initialized – initialization order of globals in separate files is non-deterministic). A more sane approach (explained by Scott Meyers in Effective C++) might be to use:


defs.h:
const UINT getUniqueMessage();

defs.c:
const UINT getUniqueMessage()
{
static UINT UNIQUE_MESSAGE = RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}")); // initialized once first time called
return UNIQUE_MESSAGE;
}

Now getUniqueMessage() can be called anywhere including during the initialization of other globals without fear of using something that may not be initialized yet.

Ripred
  • 157
  • 8
  • In function declaration, `extern` isn't required. And if it seems confusing to you, because the return type is `const UINT`, then don't worry; you cannot apply `extern` to it anyway. – Nawaz Apr 26 '11 at 08:23
  • You are correct – should have read my answer through before hitting submit. Edited my answer. – Ripred Apr 26 '11 at 08:29
  • I read it twice. I still don't see any justification of the usage of `extern` in your code. Or am I missing something? – Nawaz Apr 26 '11 at 08:30
  • @Nawaz You are correct I was just a victim of cut n paste without reviewing. – Ripred Apr 26 '11 at 08:34