C++17 [[fallthrough]]
Example:
int main(int argc, char **argv) { switch (argc) { case 0: argc = 1; [[fallthrough]]; case 1: argc = 2; }; }
Compile with:
g++ -std=c++17 -Wimplicit-fallthrough main.cpp
If you remove the [[fallthrough]];, GCC warns:
main.cpp: In function ‘int main()’: main.cpp:5:15: warning: this statement may fall through [-Wimplicit-fallthrough=] argc = 1; ~~^~~ main.cpp:6:9: note: here case 1: ^~~~
Also note from the example that the warning only happens if you fall beacross two cases: the last case statement (case 1 here) generates no warnings even though it has no break.
The following constructs don't generate the warning either:
#include <cstdlib> [[noreturn]] void my_noreturn_func() { exit(1); } int main(int argc, char **argv) { // Erm, an actual break switch (argc) { case 0: argc = 1; break; case 1: argc = 2; } // Return also works. switch (argc) { case 0: argc = 1; return 0; case 1: argc = 2; } // noreturn functions are also work. // https://stackoverflow.com/questions/10538291/what-is-the-point-of-noreturn/47444782#47444782 switch (argc) { case 0: argc = 1; my_noreturn_func(); case 1: argc = 2; } // Empty case synonyms are fine. switch (argc) { case 0: case 1: argc = 2; } // Magic comment mentioned at: // https://stackoverflow.com/a/45137452/895245 switch (argc) { case 0: argc = 1; // fall through case 1: argc = 2; } switch (argc) { // GCC extension for pre C++17. case 0: argc = 1; __attribute__ ((fallthrough)); case 1: argc = 2; } switch (argc) { // GCC examines all braches. case 0: if (argv[0][0] == 'm') { [[fallthrough]]; } else { return 0; } case 1: argc = 2; } }
We can see from the last one that GCC examines all possible branches, and warns if any of them don't have [[fallthrough]]; or break or return.
You might also want to check for feature availability with macros as in this GEM5 inspired snippet:
#if defined __has_cpp_attribute #if __has_cpp_attribute(fallthrough) #define MY_FALLTHROUGH [[fallthrough]] #else #define MY_FALLTHROUGH #endif #else #define MY_FALLTHROUGH #endif
See also: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
Tested on GCC 7.4.0, Ubuntu 18.04.
See also
C version of this question: How to do an explicit fall-through in C
[[fallthrough]];(note - needs the;) source: en.cppreference.com/w/cpp/language/attributes-std=c++17is just testing one configuration under Fedora 26 because it supplies GCC 7. But I would entertain a macro to abstract it for portability.BOOST_FALLTHROUGHdoes what you need. boost.org/doc/libs/master/libs/config/doc/html/boost_config/…__has_feature(x)works for this? Is it enough to test with__has_feature(fallthrough)? Or do we need to do this with compiler version tests? Or maybe something else?