Can “construct on first use” idiom fail under any circumstances?

随声附和 提交于 2019-12-03 16:04:55

Yes this is quite possible when static linking.

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 a call got getString() it is OS specific which version of getString() will be called. On most systems the load order of the individual shared library is used but on others it will do a depth first search of the shared libraries (ie lib X loads XA XB and Y loads YA YB. search order could be X XA XB Y YA YB or X Y XA XB YA YB). You need to consult each OS shared library documentation to understand how symbols are searched for at runtime.

The solution here is to only link against shared libraries (the default in most situations).
That way you only get one copy of libA (assuming you made libA a shared lib) and its content loaded into runtime only once (with no copies).

Note: This is not a failure at the language level.
This a failure caused by linking which is beyond the scope of the C/C++ language.

Actually there was one missing think in example. It should look like this:

string& GetString() {
  static string strFilename;
  return strFilename;
}

extern "C" {
  void PrintToScreen() {
    printf("String: %s\n", GetString().c_str())
  }
}

Strange. Anyway, I refactored it to something like this:

extern "C" {
  string* GetString() {
    static string strFilename;
    return &strFilename;
  }

  void PrintToScreen() {
    printf("String: %s\n", GetString()->c_str())
  }
}

And it works without problem now.
Still it seems strange to me that compiler was not complaining.
Thanks to all for their contribution, problem is solved now.

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

I experienced this problem again later so it was not proper fix.
The real problem was some singleton which was initialized
in meantime and had in the class constructor:

GetString() = "";

So, simple problem, but really hard to track...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!