nm 既是“U”又是“T”,是什么意思?

Ben*_*mer 6 c++ undefined-symbol nm

我在运行时遇到未定义的符号错误,当我在相关库中查找符号时,我得到结果:

nm -C -D /home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit/libScannerBitCAPI.so | grep empty_
                 U YAML::detail::node_data::empty_scalar[abi:cxx11]
00000000002b5860 T YAML::detail::node_data::empty_scalar[abi:cxx11]()
Run Code Online (Sandbox Code Playgroud)

但这怎么可能呢?该符号既未定义,又在库中?什么?或者这些实际上是不同的符号?当损坏时,名称确实略有不同:

nm -D /home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit/libScannerBitCAPI.so | grep empty_
                 U _ZN4YAML6detail9node_data12empty_scalarB5cxx11E
00000000002b5860 T _ZN4YAML6detail9node_data12empty_scalarB5cxx11Ev
Run Code Online (Sandbox Code Playgroud)

这有道理吗?

小智 2

yaml-cpp 有两种变体:

https://github.com/jbeder/yaml-cpp

https://github.com/jbeder/yaml-cpp.new-api

在第一个中,相关符号被声明为 member static const std::string& empty_scalar();。在第二个中,它被声明为 member static std::string empty_scalar;

您看到的两个符号名称与这两个不同的声明相匹配。empty_scalar如果编译器发现这样的声明不一致,则不应允许这样做。

我认为您链接了使用声明该符号的不同版本的头文件编译的目标文件。然后,链接器会认为这两个符号由于名称不同而不同。您使用的目标文件确实包含旧 api 变体的定义,但某些代码正在使用新的。