COMPILE_ASSERT 爱被打了一巴掌 2022-09-29 13:51 190阅读 0赞 最近在看chrome的代码,发现了有个叫COMPILE\_ASSERT的宏,用于编译时做判断。COMPILE\_ASSERT宏的实现在D:/project/chrome/src/src/base/basictypes.h ,注释部分有其原理的介绍,如下: // The COMPILE_ASSERT macro can be used to verify that a compile time // expression is true. For example, you could use it to verify the // size of a static array: // // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, // content_type_names_incorrect_size); // // or to make sure a struct is smaller than a certain size: // // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); // // The second argument to the macro is the name of the variable. If // the expression is false, most compilers will issue a warning/error // containing the name of the variable. template <bool> struct CompileAssert { }; #undef COMPILE_ASSERT #define COMPILE_ASSERT(expr, msg) / typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] // Implementation details of COMPILE_ASSERT: // // - COMPILE_ASSERT works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // // - The simpler definition // // #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] // // does not work, as gcc supports variable-length arrays whose sizes // are determined at run-time (this is gcc's extension and not part // of the C++ standard). As a result, gcc fails to reject the // following code with the simple definition: // // int foo; // COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is // // not a compile-time constant. // // - By using the type CompileAssert<(bool(expr))>, we ensures that // expr is a compile-time constant. (Template arguments must be // determined at compile-time.) // // - The outter parentheses in CompileAssert<(bool(expr))> are necessary // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written // // CompileAssert // // instead, these compilers will refuse to compile // // COMPILE_ASSERT(5 > 0, some_message); // // (They seem to think the ">" in "5 > 0" marks the end of the // template argument list.) // // - The array size is (bool(expr) ? 1 : -1), instead of simply // // ((expr) ? 1 : -1). // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. 主要是用了数组的长度不能小于0的特性,例如int a\[-1\]会在编译时会报错。为了兼容各个编译器,使用了模板技术。 在msdn上,也有一篇文章来介绍COMPILE\_ASSERT:[http://blogs.msdn.com/b/abhinaba/archive/2008/10/27/c-c-compile-time-asserts.aspx][http_blogs.msdn.com_b_abhinaba_archive_2008_10_27_c-c-compile-time-asserts.aspx] 在boost里面,与COMPILE\_ASSERT相似有*BOOST\_STATIC\_ASSERT*,实现可以参考:[http://www.boost.org/doc/libs/1\_36\_0/boost/static\_assert.hpp][http_www.boost.org_doc_libs_1_36_0_boost_static_assert.hpp] 在搜索代码时,发现了一个库[mili][]([http://code.google.com/p/mili/][mili]),这里面也有一个compile\_assert的实现([http://code.google.com/p/mili/source/browse/trunk/include/compile\_assert.h][http_code.google.com_p_mili_source_browse_trunk_include_compile_assert.h])。这个库还有其他一些实用的类和特性,例如Properties([http://code.google.com/p/mili/wiki/Properties][http_code.google.com_p_mili_wiki_Properties])。Properties的实现原理可以参考[http://xiaolingyao.spaces.live.com/blog/cns!6A8F02D95D2DDE46!201.entry?sa=991256254][http_xiaolingyao.spaces.live.com_blog_cns_6A8F02D95D2DDE46_201.entry_sa_991256254]。 [http_blogs.msdn.com_b_abhinaba_archive_2008_10_27_c-c-compile-time-asserts.aspx]: http://blogs.msdn.com/b/abhinaba/archive/2008/10/27/c-c-compile-time-asserts.aspx [http_www.boost.org_doc_libs_1_36_0_boost_static_assert.hpp]: http://www.boost.org/doc/libs/1_36_0/boost/static_assert.hpp [mili]: http://code.google.com/p/mili/ [http_code.google.com_p_mili_source_browse_trunk_include_compile_assert.h]: http://code.google.com/p/mili/source/browse/trunk/include/compile_assert.h [http_code.google.com_p_mili_wiki_Properties]: http://code.google.com/p/mili/wiki/Properties [http_xiaolingyao.spaces.live.com_blog_cns_6A8F02D95D2DDE46_201.entry_sa_991256254]: http://xiaolingyao.spaces.live.com/blog/cns!6A8F02D95D2DDE46!201.entry?sa=991256254
还没有评论,来说两句吧...