0

I encountered something strange this morning in my work and I really need to talk about it, I have a string object in an unnamed namespace in a header file, this last is included in the main cpp file and in other cpp files.

In main(), I have noticed when this global string object is using its =operator to set a value returned from a function (a non empty string), it stays empty ! whereas if I change the global string by a local string, this last is correctly updated with the new content. I remember encountering bizarre behavior from global variables and I really want to know what's going on. It's like the compiler didn't compile the program correctly...

Is there some people who encountered something similar with global variables and understood what happened ?

I fixed the problem by repalcing the unnamed namespace with a class and declaring the string static inside it.

Aminos
  • 754
  • 1
  • 20
  • 40
  • could you post some code to give your question more context. – Halfpint Sep 29 '16 at 20:50
  • I need to reproduce the issue, I will do it tomorrow – Aminos Sep 29 '16 at 20:50
  • 5
    "I have a string object in an unnamed namespace **in a header file**" - then you've got a separate copy of this variable for every file that includes the header. – user2357112 Sep 29 '16 at 20:50
  • @user2357112 and if I declare it "static" it will have the same behavior, isn't it ? – Aminos Sep 29 '16 at 20:52
  • mmmm so if main.cpp has its own copy of g_strMyString why this last stays empty whereas it has been used in main function ? is there another g_strMyString that effectively has been received the new content ? – Aminos Sep 29 '16 at 20:55
  • 1
    Hey dude, a team member of mine had the same problem today. just use `constexpr std::string value = "value"` (emphasis on *constexpr*) this should do it. Don't do static variables in a header file, it acts weird. – Giora Guttsait Sep 29 '16 at 21:05
  • 2
    @Aminos First off- never instantiate variables inside header files. It causes all sorts of problems (including this). Second, if you want to reference the same variable from multiple .cpp files then you need to instantiate it in one .cpp file and declare it as extern in other .cpp files (or in a header file). – David Sep 29 '16 at 21:16

2 Answers2

2

If your string is declared in a header file, and your header file is included in different .cpp files, then you don't have a single global variable, but you're declaring a separate global variable for each .cpp file.

https://en.wikipedia.org/wiki/Translation_unit_(programming)

How to share one static variable with multiple translation unit?

Community
  • 1
  • 1
David
  • 1,624
  • 11
  • 13
2

Do not use unnamed namespaces in header files.

The unnamed namespace will create a new anonymous namespace for each file it is included in and an unnamed namespaces can only appear once in a file so only one header with an unnamed namespace can be used.

Using a named namespace or a class (like you mention in your question) will work better.

ChetS
  • 658
  • 7
  • 15
  • My team member had this problem just today, and his constants were in a namespace. what eventually helped was `constexpr` – Giora Guttsait Sep 29 '16 at 21:06
  • @GioraGuttsait: Using `constexpr` **masks** the bug, but doesn't solve it. If you want to share a piece of data across compilation units, just **declare** it in the header (using the `extern` specifier), and define it in a single compilation unit. – IInspectable Oct 12 '16 at 21:36