Getting "_Static_assert is a C11-specific feature" with -std=c99 on FreeBSD

Viewed 120

Reduced to simplest reproducible size:

#include <assert.h>

#ifdef static_assert
static_assert(1 == 1, "oops!");
#endif

compiled with -std=c99 -pedantic gives warning: _Static_assert is a C11-specific feature [-Wc11-extensions] on FreeBSD (tested on 11.2 and 12.3, which use clang 6.0 and 10.0 respectively).

I don't get this problem on Linux (static_assert does not get defined when std=c99 is specified) with either gcc or clang (various versions).

The #ifdef guard is specifically to avoid the problem of trying to use a C11 feature when it's not available!

(As I said, this is the smallest reproducible size. Actually I want to define my own static_assert if there's not one available, and have the source code compile cleanly on as many systems as possible.)

On FreeBSD, assert.h defines static_assert if __ISO_C_VISIBLE >= 2011. __ISO_C_VISIBLE is being set by default in sys/cdefs.h.

On Linux, assert.h defines static_assert if __USE_ISOC11 is defined, and __USE_ISOC11 is defined by features.h if _ISOC11_SOURCE is defined.

I'm somewhat surprised that __STDC_VERSION__ is not being checked on FreeBSD (the Linux version will define static_assert if __STDC_VERSION__ >= 201112L). But on both I'm somewhat surprised that a lower value of __STDC_VERSION__ isn't being used to restrict the feature.

I can work around this with some FreeBSD-specific checks, but is FreeBSD doing it "wrong" or is Linux doing it "wrong"?

1 Answers

I can work around this with some FreeBSD-specific checks, but is FreeBSD doing it "wrong" or is Linux doing it "wrong"?

The default compiler for FreeBSD is clang and the default for Linux is gcc. In the case of FreeBSD, clang is used for the base system and uses a custom crafted Makefile authored by FreeBSD.

I also tested this on macOS which is a FreeBSD derived OS. It worked as expected.

FreeBSD's clang seems to have a deviation. Whether or not it is a bug or intentionally needed to build the base system correctly, I do not know.

So in a strict answer to your question, FreeBSD is doing something wrong here.

Clang 13.0.0 on FreeBSD-13.1:

% cc -std=c99 -pedantic -o m m.c
m.c:4:1: warning: '_Static_assert' is a C11 extension [-Wc11-extensions]
Related