【问题标题】:Is there a static_assert replacement which satisfies the C99 standard?是否有满足 C99 标准的 static_assert 替代品?
【发布时间】:2013-12-06 14:10:40
【问题描述】:

我一直在尝试实现类似于 C++11 标准中定义的static_assert 的方法。主要问题是 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." 的东西会非常好,有什么建议吗?

【问题讨论】:

  • 不,那是不可能的。使用旧标准唯一可以得到的就是吐出变量名。
  • “我可以让编译器写出像 A_is_not_POD 这样的消息”如何展示你已经为实现这一目标所做的工作?这会让你的问题更清楚。在重新修改之前,FAQ 曾经说过“最好的问题都包含一些源代码”。
  • 真可惜。但是我们在哪里可以找到 static_assert 函数的源代码呢?有趣的是编译器如何将字符串写入编译器消息。我一直在尝试以某种方式使用模板,但到目前为止没有成功。
  • @Shubham C++11 的static_assert 不是一个函数——它是一个关键字,就像forfor 也没有源代码。这就是为什么编译器可以对参数做任何它真正想做的事情。
  • 我猜这是不可能的,因为 Boost 的静态断言无法在 C++03 中打印消息。据推测,他们非常努力地寻找方法。如果在 C++03 中是不可能的,那么在 C99 中几乎肯定是不可能的。

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


【解决方案1】:

不确定我是否理解问题,但 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; \
})

【讨论】:

  • 那真是太好了。我不知道我们可以做这样的事情!!!很遗憾,clang 不提供此功能。但是,将环顾四周。非常感谢!!!
【解决方案2】:

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

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

C++ 编译器 检测到代码中的错误,并根据它所拥有的每个已知错误的标准消息列表打印出适当的错误消息。在 c99 中,编译器不知道“static assert error”是什么,所以你需要引起一些other错误

但是,由于使用 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 的错误消息是打印您自己的信息的一种方式。您可以故意使用各种其他技术/黑客,例如错误的模板、枚举link

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

【讨论】:

    猜你喜欢
    • 2011-01-09
    • 1970-01-01
    • 2017-03-25
    • 2013-08-27
    • 2013-08-23
    • 2010-09-13
    • 2013-01-29
    • 2011-01-19
    • 2020-06-11
    相关资源
    最近更新 更多