在任何情况下,"首次使用时构建"成语都会失败吗?

Pio*_*lka 5 c++ linker static static-initialization

我正在使用一些静态库构建我的程序(实际测试).
这个库包含一个文件,我在其中有这样的函数:

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

void PrintToScreen() {
    printf("String: %s\n", GetString().c_str())
}
Run Code Online (Sandbox Code Playgroud)

然后在我的main.cpp(库外)我正在做:

GetString() = "abc";
printf("String: %s\n", GetString().c_str());
PrintToScreen();
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

String: abc
String:
Run Code Online (Sandbox Code Playgroud)

所以看起来像是对函数的第二次调用(但是从库中的不同文件完成)以某种方式清除以前的值,重新初始化它,或者使用它自己的副本.
我更改了GetString函数以使用'new'但结果完全相同(btw.程序从不崩溃).
但我不明白热可能吗?
我有什么想法我做错了吗?

-------------------------------更新------------------ ------------

  1. 测试完成的是单线程环境.
  2. 它适用于某些平台,有些则不适用(适用于Windows,MacOS和AIX,不适用于Linux,HP_UX,Solaris,FreeBSD ...)
  3. 我在执行期间验证了strFilename的地址(在GetString中的printf),看起来它是一个没有重复的变量(地址总是相同的)
  4. 但是,在最终的lib上使用nm我会得到类似的东西:

0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b _ZZ16GetLogprintfFilevE16strLogprintfFile
U _Z16GetLogprintfFilev

并且在我的基础库上使用nm(由最终的lib使用),我得到:

0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b _ZZ16GetLogprintfFilevE16strLogprintfFile

Pio*_*lka -1

实际上,示例中缺少一个想法。它应该看起来像这样:

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

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

奇怪的。无论如何,我将其重构为这样的:

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

  void PrintToScreen() {
    printf("String: %s\n", GetString()->c_str())
  }
}
Run Code Online (Sandbox Code Playgroud)

现在它可以正常工作了。
对我来说,编译器没有抱怨仍然很奇怪。
感谢大家的贡献,现在问题已经解决了。

- - - - - - - - - - - - - - - - - 编辑 - - - - - - - - -------------------

后来我又遇到了这个问题,所以没有得到正确的解决。
真正的问题是一些单例,它
同时被初始化并在类构造函数中:

GetString() = "";
Run Code Online (Sandbox Code Playgroud)

所以,简单的问题,但真的很难跟踪......