12

I have been trying to implement a method similar to static_assert which is defined in the C++11 standard. The main problem is how does the C++ compiler write the text message being passed to static_assert as a const char*? I can get the compiler to write a message like A_is_not_POD. This is what I have:

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

But it would be quite nice to get the compiler to write something like "Error: A is not POD." Any suggestions?

4

2 回答 2

6

不确定我是否理解问题,但 C11 有_Static_assert(condition, errmessage)。在 C99 中缺少此功能,但根据编译器,可以进行模拟。例如 gcc(不幸的是 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; \
})
于 2013-12-07T03:35:26.403 回答
3

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

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

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

但是,因为使用 c99 编译器创建静态断言有点像 hack,所以它不能完全按照您的意愿打印出漂亮的错误消息。

对于你的例子,

#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

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

于 2013-12-07T03:23:22.453 回答