C++11 introduced standard attributes: a way to mark fragments of code with useful information for the developer or optimization information for the compiler. See a complete list of standard attributes here, Clang attributes here, and Microsoft attributes here. I will go over a few of them in this post.
- [[nodiscard]] – when specified with a function declaration, tells the compiler to emit a warning if function’s return value is ignored; when specified with a struct emits a warning wherever the struct is returned and ignored.
- [[fallthrough]] – suppresses compiler warning about a switch-case statement without a break; in other words, a case statement that falls through into another case.
- [[no_unique_address]] – tells the compiler to perform empty base optimization on marked data member.
- [[deprecated]] – emits a warning when marked function, struct, namespace, or variable is used.
- [[noreturn]] – tells the compiler that the marked function never returns; emits a warning if it does.
- [[maybe_unused]] – suppressed a warning when marked variable, function, or argument is not used.
- [[likely]] – tell the compiler this is the most likely path of execution; allows for optimizations.
Note: not all are supported on every compiler; I tested on LLVM 8.0.0 and GCC 8.2. Luckily the unsupported ones do not cause a compile error 🙂
Below is an example code and a screenshot of compiler messages.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
[[nodiscard]] int no_discard(int i) { switch(i) { case 1: [[fallthrough]]; [[likely]] case 2: return i; default: return i; } } struct E {}; struct [[nodiscard]] S { int i; [[no_unique_address]] E e; }; S no_discard_struct() { return {}; } struct [[deprecated("Use Q instead")]] P {}; [[deprecated("Use bar() instead")]] void foo() {} [[noreturn]] void never_returns() { while(true); } int main() { [[maybe_unused]] int unused = 1; P p; no_discard(0); no_discard_struct(); foo(); never_returns(); } |
Thanks for sharing. Didn’t know about that feature. Looks familiar compared to Java‘s annotations.
The attributes that GCC warns are unknown are part of the C++20 standard, which has only recently just been formalized. I’d expect the new attributes to be supported by most compilers pretty soon, though, since compiler extensions already exist for
[[likely]]
and
[[unlikely]]