缩小到最简单的可重现大小:
#include <assert.h>
#ifdef static_assert
static_assert(1 == 1, "oops!");
#endif
用-std=c99 -pedantic
编译给出了 FreeBSD 上的warning: _Static_assert is a C11-specific feature [-Wc11-extensions]
(在 11.2 和 12.3 上测试, 分别使用 clang 6.0 和 10.0)。
我在 gcc 或 clang(各种版本)的 Linux 上没有遇到这个问题(指定std=c99
时static_assert
没有定义)。
#ifdef
防护专门用于避免在 C11 功能不可用时尝试使用它的问题!
(正如我所说,这是最小的可重现尺寸。实际上,如果没有可用的源代码,我想定义自己的static_assert
,并在尽可能多的系统上干净地编译源代码。
在 FreeBSD 上,assert.h
定义了static_assert
if__ISO_C_VISIBLE >= 2011
。 默认情况下,__ISO_C_VISIBLE
在sys/cdefs.h
中设置。
在 Linux 上,如果定义了__USE_ISOC11
,assert.h
定义static_assert
,如果定义了_ISOC11_SOURCE
,则由features.h
定义__USE_ISOC11
。
我有点惊讶__STDC_VERSION__
没有在 FreeBSD 上检查(如果__STDC_VERSION__ >= 201112L
,Linux 版本将定义static_assert
)。 但是在两者上,我都有些惊讶,较低的__STDC_VERSION__
值没有被用来限制该功能。
我可以通过一些特定于 FreeBSD 的检查来解决这个问题, 但是 FreeBSD 是"错了"还是 Linux 做
错了?我可以通过一些特定于 FreeBSD 的检查来解决这个问题,但是 FreeBSD 做错了还是 Linux 做错了"?
FreeBSD 的默认编译器是 clang,Linux 的默认编译器是 gcc。 在 FreeBSD 的情况下, clang 用于基本系统, 并使用由 FreeBSD 编写的定制构建的 Makefile。
我也在macOS上测试了这个,这是一个FreeBSD派生的操作系统。它按预期工作。
FreeBSD 的叮当声似乎有偏差。我不知道这是否是一个错误或故意需要正确构建基本系统。
所以在严格回答你的问题时, FreeBSD 在这里做错了什么。
FreeBSD-13.1 上的 Clang 13.0.0
:% cc -std=c99 -pedantic -o m m.c
m.c:4:1: warning: '_Static_assert' is a C11 extension [-Wc11-extensions]