我已经确认这是一个问题 - Microsoft 的 Stephan T Lavavej (STL!)对此发表了博文。
具体来说,他说:
一般的问题是链接器没有诊断出所有的单一定义规则 (ODR) 违规。虽然并非不可能,但这是一个难以解决的问题,这就是为什么该标准特别允许某些 ODR 违规行为未被诊断出来。
我当然希望编译器和链接器有一种特殊的模式,可以在构建时捕获所有 ODR 违规,但我认识到这很难实现(并且会消耗可能会被更好地利用的资源,比如更多的一致性)。无论如何,通过适当地构造代码,无需付出极大的努力就可以避免 ODR 违规,因此我们作为程序员可以应对这种缺乏链接器检查的情况。
但是,通过打开和关闭来更改代码功能的宏正在危险地与 ODR 调情,具体的问题是 _SECURE_SCL 和 _HAS_ITERATOR_DEBUGGING 都是这样做的。乍一看,这似乎并没有那么糟糕,因为您应该已经可以控制在构建系统中在项目范围内定义了哪些宏。但是,单独编译的库会使事情复杂化——如果您(例如)使用 _SECURE_SCL 构建 Boost,这是默认设置,您的项目不得关闭 _SECURE_SCL。如果您打算在您的项目中关闭 _SECURE_SCL,现在您必须相应地重新构建 Boost。并且根据所讨论的单独编译的库,这可能很困难(根据我的理解,使用 Boost 可以做到,我只是从来没有弄清楚如何)。
他稍后在评论中列出了一些可能的解决方法,但没有一个看起来适合这种情况。其他人报告说在编译 boost 时可以通过在boost/config/compiler/visualc.hpp中插入一些定义来关闭这些标志,但这对我不起作用。但是,在tools/build/v2/user-config.jam中逐字插入以下行就可以了。请注意,空格对于提高 jam 很重要。
使用 msvc : 9.0 : : <cxxflags>-D _SECURE_SCL=0 <cxxflags>-D _HAS_ITERATOR_DEBUGGING=0 ;