C23 attribute specifiers
C23 specification added C++-like attribute specifiers to C. C attribute specifiers add metadata to declarations and definitions. The metadata can be used by the compiler and by the developer to help understand the code intent.
Commonly used attributes such as
[[maybe_unused]]
and
[[fallthrough]]
suppress compiler warnings.
Compilers including GCC ≥ 11 have __has_c_attribute()
to check if an attribute is supported by the compiler–even if the command line specified standard is older.
maybe_unused attribute
To enable code to fallback to no attribute with older compilers, use logic in header file like:
#if !defined(__has_c_attribute)
# define __has_c_attribute(x) 0
#endif
#if __has_c_attribute(maybe_unused)
# define MAYBE_UNUSED [[maybe_unused]]
#else
# define MAYBE_UNUSED
#endif
then in the definition:
int windows_fun(int x, MAYBE_UNUSED int y) {
#ifdef _WIN32
return y;
#else
return x;
#endif
}
On non-Windows systems, the compiler would have issued a warning about y
being an unused argument.
The [[maybe_unused]]
attribute suppresses that warning.
fallthrough attribute
The [[fallthrough]]
attribute is used to indicate that a fall-through in a switch statement is intentional.
This attribute can be used to suppress warnings about missing break
statements in a switch
block.
In declaration (header) file do like:
#ifndef __has_c_attribute
#define __has_c_attribute(x) 0
#endif
#if __has_c_attribute(fallthrough)
// GCC >= 11
#define FALLTHROUGH [[fallthrough]]
#elif defined(__GNUC__) && __GNUC__ >= 7 || defined(__clang__) && __clang_major__ >= 12
#define FALLTHROUGH __attribute__((fallthrough))
#else
#define FALLTHROUGH
#endif
then in the definition:
switch (x) {
case 1:
x++;
FALLTHROUGH;
case 2:
x--;
}