Gold 没有对此发出警告的原因是 Gold 只检测符号不匹配(同一符号以不兼容的方式在多个目标文件中定义),示例中不存在此类不匹配。
在 Valgrind 下运行示例确实会产生此错误:
valgrind --track-origins=yes ./a.out
==11004== Memcheck, a memory error detector
==11004== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==11004== Using Valgrind-3.8.0.SVN and LibVEX; rerun with -h for copyright info
==11004== Command: ./a.out
==11004==
==11004== Conditional jump or move depends on uninitialised value(s)
==11004== at 0x40B6D24: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib64/libstdc++.so.6.0.16)
==11004== by 0x40B703C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib64/libstdc++.so.6.0.16)
==11004== by 0x40C26DE: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib64/libstdc++.so.6.0.16)
==11004== by 0x40094F: A<int>::f() (a.h:6)
==11004== by 0x4008CB: f(A<int>*) (a.cpp:3)
==11004== by 0x400977: main (main.cpp:7)
==11004== Uninitialised value was created by a stack allocation
==11004== at 0x400964: main (main.cpp:5)
您应该从Address Sanitizer获得更好的报告:
更新:
关键是我想在链接时检测错误,而不是在执行期间。
我理解你的意思,但编译器(没有关于其他翻译单元的信息)或链接器(没有关于所涉及的类型的信息)目前不可能警告你这一点。
现在,对于调试版本,链接器理论上可以这样做,如果它还为每个函数比较参数类型的调试信息。我建议在bugzilla中提交黄金功能请求。