【发布时间】:2021-06-30 07:22:22
【问题描述】:
_Static_assert 内置于一些 C 编译器,例如 gcc 和 clang,但它可能不会包含在所有 C 编译器中。我想使用_Static_assert 功能,同时让我的代码尽可能跨平台。我认为最好的方法是测试
#ifdef _Static_assert
_Static_assert(0, "Test");
#endif
但这似乎并不奏效。它可以编译,但没有检测到 _Static_assert 已定义。然后我想我可以测试编译器是否是 GCC,但我读到定义 __GNUC__ 并不一定证明使用的编译器是 GCC。这也不会检测到我可能不知道的定义了_Static_assert 的其他编译器。所以我的问题是,检测编译器是否在预处理器中支持_Static_assert 的最佳方法是什么?
编辑: 这是我想出的适合我目的的解决方案。感谢下面的@KamilCuk 提供了帮助我的链接。
// Check that we can use built-in _Static_assert
#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
#define WE_HAVE_STATIC_ASSERT 1
#endif
#if WE_HAVE_STATIC_ASSERT
_Static_assert(0, "Test");
#endif
此代码在 gcc 和 clang 上都适用于我:https://godbolt.org/z/svaYjWj4j
最终编辑(我认为):这为我最初关于如何检测_Static_assert 是否可用的问题提供了答案。它还提供了一个备用选项,该选项会在我测试的大多数编译器中产生相对有用的错误。
这里是测试代码的链接:https://godbolt.org/z/TYEj7Tezd
// Check if we can use built-in _Static_assert
#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
#define MY_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
#else // We make our own
// MY_JOIN macro trick generates a unique token
#define MY_JOIN2(pre, post) MY_JOIN3(pre, post)
#define MY_JOIN3(pre, post) pre ## post
#if defined( __COUNTER__ ) // try to do it the smart way...
#define MY_JOIN(pre) MY_JOIN2(pre, __COUNTER__)
#define MY_STATIC_ASSERT(cond, msg) \
static const char *MY_JOIN(static_assert)[(cond) * 2 - 1] = { msg }
#else // we did our best...
//will break if static assert on same line in different file
#define MY_JOIN(pre) MY_JOIN2(pre, __LINE__)
#define MY_STATIC_ASSERT(cond, msg) \
static const char *MY_JOIN(static_assert)[(cond) * 2 - 1] = { msg }
#endif
#endif
/* - CHANGE CODE HERE TO TEST THE ASSERTIONS - */
enum {
A = 3,
B = 3,
C = B - A
};
/* - --------------------------------------- - */
// Test to see if the enum values match our assertions
MY_STATIC_ASSERT(B > A, "B must be greater than A");
MY_STATIC_ASSERT(C > 0, "C must be greater than zero");
我用来制作这个的有用信息来自这些链接:
http://jonjagger.blogspot.com/2017/07/compile-time-assertions-in-c.html
https://www.tutorialspoint.com/cprogramming/c_preprocessors.htm
【问题讨论】:
-
如果您使用
-std=c99编译,则无法测试__STDC_VERSION__ >= 201112L。由于_Static_assert是一个关键字,即使static_assert宏不可用
标签: c c-preprocessor static-assert