使用隐藏可见性可以避免 ODR 违规吗?

Sch*_*ZHU 6 c++ linker shared-libraries one-definition-rule rust

例如,我的一个项目中有一个稍微复杂的库依赖情况:


              /--------------------------------\
              |                                |
      /----> GRPC <------------------\         |
      |                              |         |
      |        (c++)                 |         |        
      \-------   A  -------------->  B         |
                 |                 (rust)      |
                 |                             |
                 \------------------> c++  <---/ 
Run Code Online (Sandbox Code Playgroud)

Rust 默认情况下更喜欢使用静态链接。可执行文件 A 还构建为静态链接 lib(std)c++。因此,据我了解,A 和 B 中都会有两个 STL 实现副本。这正是https://developer.android.com/ndk/guides/cpp-support#sr建议避免的模式。

但是,查看nm -DB 的动态链接表(例如通过 );我看不到导出的 lib(std)c++/grpc 符号。这是因为 Rust 默认将它们标记为隐藏。

  • 那么,如果 B 中的所有公共符号都被隐藏,是否安全(或符合 ODR)?

Kam*_*Cuk 0

符合 ODR

单一定义规则是C++编程语言的一部分。它与C++语言有关。这与其他任何事都无关。C++“之外”不存在 ODR。C++ 标准不适用于 C++ 之外的领域,它仅涉及 C++ 编程语言。

关于语言互操作性,没有广泛采用的可移植超级标准。这些只是工具,没有定义和规则。ODR 或 C++ 中的任何其他规则在此不适用。

尝试将 C++ 标准规则应用于不相关的上下文没有什么意义。Rust 不是 C++ 的一部分。RPC 是特定于平台的,超出了 C++ 编程语言的范围。

因此,推断某些 C++ 规则在使用特定于平台的工具(共享库、“动态链接表”)并使用多种编程语言的工作链中会或不会被破坏的推理在这里并不适用。

从 C++ 的意义上来说,这一切实际上都是“未定义的行为”——C++ 标准中没有任何规则可以适用于此。

使用隐藏可见性可以避免 ODR 违规吗?

当然。