Cpper
C/C++高级工程师 Android高级软件工程师 IT集成工程师 音频工程师 熟悉c,c++,java,c#,py,js,asp等多种语言 程序猿
以前看过很长时间的boost,记得上面有STATIC_ASSERT
在loki库中也有类似的宏
1 LOKI_STATIC_CHECK(expr, msg)
其中expr代表要断言的表达式
当其为假,则让程序无法通过编译
其实现很简单
利用模板特化:

1     template<int> struct CompileTimeError;
2     template<> struct CompileTimeError<true> {};
当表达式为真则使用模板特化形式
注意其模板在这里仅仅做前向引用
再看具体的宏:
1 #define LOKI_STATIC_CHECK(expr, msg) \
2     { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } 
使用代码块(statement block)
声明一个编译时错误对象
(具体原因在于当条件为假则模板对象没有具体实现,抛出一个未定义完全的对象)
9 D:\Dev-Cpp\prj\test\main.cpp aggregate `Loki::CompileTimeError<0> ERROR_wo' has incomplete type and cannot be defined 

对于其宏的实现在我看来
(void)ERROR_##msg;这句是多余的(不知道这句的作用是什么??谁能告诉我)
posted on 2010-04-01 21:44 ccsdu2009 阅读(2531) 评论(13)  编辑 收藏 引用
Comments
  • # re: loki技法(1).静态断言
    ccsdu2009
    Posted @ 2010-04-01 21:53
    说实话 我感觉这个设计的很巧妙
    联合使用模板特化和前向声明来
      回复  更多评论   
  • # re: loki技法(1).静态断言
    OwnWaterloo
    Posted @ 2010-04-01 22:57
    为了让编译器输出的错误信息更容易理解一些:
    LOKI_STATIC_CHECK(sizeof(char)==1, bad_compiler );

    如果断言失败, 输出的就是:
    ERROR_bad_compiler 是一个不完全类型的object。
      回复  更多评论   
  • # re: loki技法(1).静态断言
    OwnWaterloo
    Posted @ 2010-04-01 22:57
    《modern c++ design》 是loki作者写的介绍该库的书。
      回复  更多评论   
  • # re: loki技法(1).静态断言
    陈梓瀚(vczh)
    Posted @ 2010-04-02 11:17
    前提是msg是英文……  回复  更多评论   
  • # re: loki技法(1).静态断言
    萌萌
    Posted @ 2010-04-02 11:59
    的确很好。

      回复  更多评论   
  • # re: loki技法(1).静态断言
    欲三更
    Posted @ 2010-04-09 02:54
    我猜想如果没有(void)ERROR_##msg;这句,编译器会把前面的变量定义优化掉从而断言失效?

    只是猜想。  回复  更多评论   
  • # re: loki技法(1).静态断言
    ccsdu2009
    Posted @ 2010-04-09 08:24
    @欲三更
    恩 这个很有可能  回复  更多评论   
  • # re: loki技法(1).静态断言
    蚂蚁终结者
    Posted @ 2010-04-10 13:06
    见过另外一种比较简洁的实现:
    #define static_assert(expr) typedef char __static_assert__[(expr) ? 1 : -1];

    如:

    static_assert(sizeof(int) == 1);

    编译错误为:"the size of an array must be greater than zero"

    不过不能够像上面那样用msg自定义错误信息!  回复  更多评论   
  • # re: loki技法(1).静态断言[未登录]
    ccsdu2009
    Posted @ 2010-04-10 19:01
    @蚂蚁终结者
    boost里面有这个东西
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;  回复  更多评论   
  • # re: loki技法(1).静态断言
    主打歌
    Posted @ 2010-09-06 23:10
    让boost, c++设计新思维统统去见鬼吧。看哥的静态断言的巧妙实现吧。

    可以在下列范围内使用(已经在vc,gcc中测试):
    在名字空间域中使用 ;
    在函数域中使用 ;
    在类域中使用 ;
    在类模板中使用 。
    在函数模板中使用 。

    比boost强大的是关键是还能支持c语言,不使用模版使得编译时间大大缩短!!还能够打印自定义的错误信息(我想这比啥都强)。
    注意:gcc 的c编译器居然允许0除以0的结果作为数组长度。此时只有警告,但是程序启动就会立即产生浮点数异常,退出。g++工作正常。vc的c编译器工作正常。
    #define JOIN(x,y) x ## y
    #define JOIN_1(x,y) JOIN(x, y)
    #define JOIN_2(x,y) JOIN_1(x, y)

    /*It's the begin of all error message.*/
    #define ERRORMSG_BEGIN ATTENTION__The_assertion_error_is__

    /*
    *To fetch a error if testnum==0||testnum==false, by divide 0.
    *Cast to int to avoid warning caused by bool division.
    */
    #define IF_ERROR(testnum) (((int)(testnum))/((int)(testnum)))


    /*
    *The errormsg only support following characters: [a-zA-Z0-9] and '_'.
    *Because it's a part of variable's name.
    *Example:STATIC_ASSERT(sizeof(int) <= sizeof(short), The_sizeof_int_is_larger_than_short__)
    *For above example, (Most) compilers can print error include following message:
    ATTENTION__The_assertion_error_is__The_sizeof_int_is_larger_than_short__234
    *The number in the end is the linenumber of the position of the macro been called.
    */
    #ifndef NDEBUG
    #ifndef _MSC_VER
    #define STATIC_ASSERT(testnum, errormsg) static char JOIN_2(JOIN_1(ERRORMSG_BEGIN,errormsg),__LINE__)[IF_ERROR(testnum)];
    #else
    #define STATIC_ASSERT(testnum, errormsg) static char JOIN_1(ERRORMSG_BEGIN,errormsg)[IF_ERROR(testnum)];
    #endif
    #else
    #define STATIC_ASSERT(testnum, errormsg)
    #endif

    //有看不懂英文的请留言咨询。  回复  更多评论   
  • # re: loki技法(1).静态断言
    主打歌
    Posted @ 2010-09-06 23:12
    我的blog
    http://user.qzone.qq.com/41656955  回复  更多评论   
  • # re: loki技法(1).静态断言
    永远在一起
    Posted @ 2010-12-15 22:09
    这让我想到了《Imperfect C++》里面的静态段元,比如说判断一个类是不是POD类,两个类型是不是拥有同一个基类,或者两个类的大小是不是一样等等。不过这些静态断言在开发中真的有作用么,作为一名学生,我还是挺怀疑的。  回复  更多评论   
  • # re: loki技法(1).静态断言
    lambda
    Posted @ 2014-12-05 17:20
    没有(void)ERROR_##msg;这句,编译器会提示ERROR_##msg变量没有使用的Warning信息,   回复  更多评论   

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理