是否有一个static_assert替换符合C99标准?

时间:2013-12-06 14:10:40

标签: c++ c++11 c99 static-assert

我一直在尝试实现类似于static_assert的方法,该方法在C ++ 11标准中定义。主要问题是C ++编译器如何将static_assert的文本消息写为const char*?我可以让编译器编写像A_is_not_POD这样的消息。这就是我所拥有的:

#define MY_STATIC_ASSERT(condition, name)         \
   typedef char name[(condition) ? 1 : -1]; 

但是让编译器编写像"Error: A is not POD."这样的建议会很好吗?

2 个答案:

答案 0 :(得分:4)

不确定我理解问题,但C11有_Static_assert(condition, errmessage)。在C99中,缺少此功能,但根据编译器,可以模拟。例如。 for gcc(unfortulately clang不支持属性(错误))

#define MY_STATIC_ASSERT(cnd, descr) ({ \
    extern int __attribute__ ((error("static assert failed: (" #cnd ") (" #descr ")"))) \
               compile_time_check(void); \
    ((cnd) ? 0 : compile_time_check()), 0; \
})

答案 1 :(得分:2)

在c99标准中,没有“官方”方法在C ++编译器中执行静态断言。

  

“主要问题是C ++编译器如何将传递给static_assert的文本消息写为const char *?”

C ++ 编译器检测到代码中的错误,并根据已知可能遇到的每个错误的标准消息列表打印出相应的错误消息。在c99中,编译器不知道“ 静态断言错误”是什么,因此您需要导致一些 其他错误

但是,因为使用c99编译器创建静态断言是一种破解,它无法准确地打印出你想要的错误消息。

对于您的示例,

#define MY_STATIC_ASSERT(condition, name)         \
    typedef char name[(condition) ? 1 : -1];
MY_STATIC_ASSERT(false, my_error_msg)

会在 gcc 编译器中触发"error: size of array ‘my_error_msg’ is negative"消息(并且在其他编译器中应该发出类似的消息,您希望!)。为数组提供name的错误消息是打印您自己的信息的一种方法。您可以有目的地使用各种其他技术/黑客,例如错误的模板,枚举link

注意: 可以使用预处理器宏(例如#error)在C ++ 11之前提供自定义编译器消息或#pragma。但预处理时间编译时不同!预处理器评估许多表达式和关键字的能力有限,例如"if""sizeof""return"等对预处理器没有任何意义,只有编译器link with some overview