在GotW 94中,Herb Sutter区分了"经典C++"声明
const char* s = "Hello";
Run Code Online (Sandbox Code Playgroud)
和"现代"风格
auto s = "Hello";
Run Code Online (Sandbox Code Playgroud)
他告诉我们,有一个"中的类型细微的差别s,这里的auto风格是比较正确的." [编辑补充:评论表明,这可能不是Sutter实际意义的公平表示; 见下面的讨论.]
但是......有什么区别?我的印象是a const char *是引用字符串文字的正确方法.此外,当我问我的调试器(lldb)时,它似乎认为类型实际上是相同的:
* thread #1: tid = 0x1756c2, 0x0000000100000f8f test`main + 31 at test.cc:4, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000f8f test`main + 31 at test.cc:4
1 int main(void) {
2 const char* s = "Hello";
3 auto t = "Hello";
-> 4 return 0;
5 }
(lldb) fr v
(const …Run Code Online (Sandbox Code Playgroud) 我有一个简单的C++代码,看起来像这样:
#include <boost/timer/timer.hpp>
int main(void) {
boost::timer::auto_cpu_timer t;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我尝试编译并链接它(使用gcc 4.8.1和GNU ld 2.23.52.20130828),如下所示:
$ g++ -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
一种解决方案是-lboost_system在命令行上明确提及,这是有效的.但是,我也可以这样做:
$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer
Run Code Online (Sandbox Code Playgroud)
根据ld文档"with --copy-dt-needed-entries命令行中提到的动态库将被递归搜索,跟随其DT_NEEDED标记到其他库,以便解析输出二进制文件所需的符号",所以这一切都有意义:ld正在从boost_timer中找出它还需要链接boost_system以解析所有符号.
但是,我意识到这也有效:
$ g++ -fPIC -shared -o test test.cc -lboost_timer
Run Code Online (Sandbox Code Playgroud)
显然,我现在已经生成了一个共享对象而不是一个可执行文件.显然,ld能够弄清楚它需要将该共享对象与boost_system链接:
$ ldd test | grep boost_system
libboost_system.so.1.54.0 => /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:为什么在构建共享对象与可执行文件时,符号解析会有所不同?如何在没有指定的情况下ld能够确定我的共享对象应该与boost_system链接--copy-dt-needed-entries?