Can an “idiom build upon first use” under any circumstances?

I am building my program (tests actually) using some static library.
This library contains one file inside which I have functions like this:

string& GetString() { static string strFilename; return strFilename; } void PrintToScreen() { printf("String: %s\n", GetString().c_str()) } 

Then in my main.cpp (outside the library) I do:

 GetString() = "abc"; printf("String: %s\n", GetString().c_str()); PrintToScreen(); 

And I get this output:

 String: abc String: 

It looks like the second function call (but is made from another file that is inside the library) somehow clear the previous value, reinitialize it or use your own copy.
I changed the GetString function to use "new", but the result is exactly the same (by the way, the program never crashes).
But I do not understand how possible this is?
Any ideas what I'm doing wrong?

------------------------------- UPDATE --------------- --- ------------

  • Testing is performed in a single-threaded environment.
  • It works on some platforms, and on some it does not work (works with windows, MacOS and AIX, does not work on Linux, HP_UX, Solaris, FreeBSD ...)
  • I checked the strFilename address at runtime (printf inside GetString) and looks like one variable without duplicates (the address is always the same)
  • BUT, with nm in the last lib, I get something like this:

<i> 0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b_ZZ16GetLogprintfFilevE16strLogprintfFile
U_Z16GetLogprintfFilev

and with nm on my lib base (using the final lib) I get:

<i> 0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b_ZZ16GetLogprintfFilevE16strLogprintfFile

+5
source share
2 answers

Actually, the missing example was missing from the example. It should look like this:

 string& GetString() { static string strFilename; return strFilename; } extern "C" { void PrintToScreen() { printf("String: %s\n", GetString().c_str()) } } 

It’s strange. Anyway, I reorganized it to something like this:

 extern "C" { string* GetString() { static string strFilename; return &strFilename; } void PrintToScreen() { printf("String: %s\n", GetString()->c_str()) } } 

And now it works without a problem.
It seems strange to me that the compiler did not complain.
Thanks to everyone for their contribution, the problem is solved now.

---------------------------------- EDIT ------------ --- -------------------

I ran into this problem again, so it was wrong.
The real problem was some singleton that was initialized
at the same time in the class constructor:

 GetString() = ""; 

So, a simple problem, but very difficult to track ...

-1
source

Yes, this is entirely possible with static binding.

Example:

  libA.a // contains GetString() // Contains. PrintToScreen() // Here the reference has been resolved. libX.so // Contains a call to GetString() // This library is linked with libA.a // Thus pulls in the function GetString() into this library. libY.so // Contains a call to PrintToScreen() // This library is linked with libA.a // Thus pulls in the function PrintToScreen and GetString() into this library. a.out // linked against libY.so libX.so // This has two distinct versions of GetString() 

In the above example, if a.out contains the call to getString () called, it is the specific OS which version of getString () will be called. Most systems use the load order of a separate shared library, but on others it will perform the depth of the first search for shared libraries (i.e. lib X loads XA XB and Y loads YA YB. The search order can be X XA XB Y YA YB or XY XA XB YA YB). You need to consult the documentation for the common OS library to understand how to search for characters at runtime.

The solution here is to link only to shared libraries (the default in most situations).
This way you get only one copy of libA (assuming you created libA for the shared library), and its contents are loaded at runtime only once (without copies).

Note. This is not a language level error.
This is an error caused by binding that goes beyond the scope of the C / C ++ language.

+3
source

All Articles