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://mcmap.net/q/116342/-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://mcmap.net/q/119128/-gcc-7-wimplicit-fallthrough-warnings-and-portable-way-to-clear-them
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 – Purvey-std=c++17
is just testing one configuration under Fedora 26 because it supplies GCC 7. But I would entertain a macro to abstract it for portability. – ClydeBOOST_FALLTHROUGH
does what you need. boost.org/doc/libs/master/libs/config/doc/html/boost_config/… – Aeneous__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? – ClydeBOOST_FALLTHROUGH;
in your code and then it just expands to the right thing to cancel the warning. If the compiler in use warns, but does not have a way to silence the warning, there's nothing we can do anyways I guess. – Aeneous