我正在尝试使用boost :: signal来实现一个回调机制,即使是最简单的库使用,我也会在boost :: signal代码中获得内存访问断言.我把它简化为这段代码:
#includetypedef boost::signal Event; int main(int argc, char* argv[]) { Event e; return 0; }
谢谢!
编辑:这是使用Visual Studio 2008 w/SP1编译的Boost 1.36.0.Boost :: filesystem,像boost :: signal也有一个必须链接的库,它似乎工作正常.我相信,我使用的所有其他boost库都只是标题.
我已经证实这是一个问题 - 微软的Stephan T Lavavej(STL!)在博客中写到这一点.
具体来说,他说:
一般问题是链接器不诊断所有一个定义规则(ODR)违规.虽然并非不可能,但这是一个难以解决的问题,这就是为什么标准特别允许某些ODR违规未被诊断的原因.
我当然希望编译器和链接器能够在构建时捕获所有ODR违规的特殊模式,但我认识到这很难实现(并且会消耗可能更好地使用的资源,例如更一致).无论如何,通过正确构建代码,可以避免ODR违规,而不需要付出极大的努力,因此我们作为程序员可以应对这种缺少的链接器检查.
但是,通过打开和关闭来改变代码功能的宏正在与ODR进行危险的调情,具体问题是_SECURE_SCL和_HAS_ITERATOR_DEBUGGING都是这样做的.乍一看,这可能看起来不那么糟糕,因为您应该已经可以控制在构建系统中项目范围内定义的宏.但是,单独编译的库会使事情变得复杂 - 如果您使用_SECURE_SCL构建(例如)Boost,这是默认设置,则您的项目不能关闭_SECURE_SCL.如果您打算在项目中关闭_SECURE_SCL,那么现在必须相应地重新构建Boost.根据所讨论的单独编译的库,这可能很难(根据我的理解,使用Boost,它可以完成,我从来没有弄清楚如何).
他在后面的评论中列出了一些可能的解决方法,但没有一个看起来适合这种情况.有人报道能够通过插入一些定义编译的刺激时,关闭这些标志升压/配置/编译器/ visualc.hpp,但这丝毫不为我工作.但是在tools/build/v2/user-config.jam中插入以下行VERBATIM就可以了.请注意,空格对于增加阻塞非常重要.
using msvc : 9.0 : :-D _SECURE_SCL=0 -D _HAS_ITERATOR_DEBUGGING=0 ;