9

Code sample:

int main(int argc, char **argv)
{
    switch(argc)
    {
    case 0:
        argc = 5;
        __attribute__((fallthrough));

    case 1:
        break;
    }
}

Using gcc 6.3.0, with -std=c11 only, this code gives a warning:

<source>: In function 'main':
7 : <source>:7:3: warning: empty declaration
   __attribute__((fallthrough));
   ^~~~~~~~~~~~~

What is the correct way to use this without eliciting a warning?

M.M
  • 138,810
  • 21
  • 208
  • 365
  • 2
    If you compare [the 6.4 documentation](https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/) and [the 7.1 documentation](https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/), it seems statement attributes like that was added in version 7. – Some programmer dude Jul 27 '17 at 11:22
  • Not an answer, but the 6.3 manual completely lacks the "statement attribute' section that is present in 7.1, where `fallthrough` is described. I'm thinking it's simply not supported for 6.3. The diagnostic is because GCC doesn't simply ignore the unknown attribute, and sees it as a declaration [that violates this constraint](http://port70.net/~nsz/c/c11/n1570.html#6.7p2) – StoryTeller - Unslander Monica Jul 27 '17 at 11:22
  • @StoryTeller that makes sense – M.M Jul 27 '17 at 11:41

3 Answers3

12

As previously answered, __attribute__ ((fallthrough)) was introduced in GCC 7. To maintain backward compatibility and clear the fall through warning for both Clang and GCC, you can use the /* fall through */ marker comment.

Applied to your code sample:

int main(int argc, char **argv)
{
    switch(argc)
    {
    case 0:
        argc = 5;
        /* fall through */

    case 1:
        break;
    }

    return 0;
}
jyvet
  • 2,021
  • 15
  • 22
  • Both the marker comment or attribute can be use after the code on the same line, or below. – David C. Rankin Feb 09 '18 at 09:44
  • Not without a warning. With the attribute `warning: empty declaration` will be returned on older GCC versions (< 7.x). – jyvet Feb 09 '18 at 10:51
  • Sorry, the GCC7 was implied. – David C. Rankin Feb 09 '18 at 16:53
  • 2
    The fall though comment is horrible compiler design, Combined preprocessing and compiling and combiling the same file after it's been preprocessed separately should produce the same warnings/errors, but that can't work if you have special magic comments. – Petr Skocik Sep 16 '19 at 14:03
8

Tried to comment previous, but did not have 50 reputation.

So, my experiences:

1) the feature is since gcc 7, so using attribute on older compilers will give warning. therefore I currently use:

#if defined(__GNUC__) && __GNUC__ >= 7
 #define FALL_THROUGH __attribute__ ((fallthrough))
#else
 #define FALL_THROUGH ((void)0)
#endif /* __GNUC__ >= 7 */

and then I use FALL_THROUGH; in code

(Some day I figure out what is needed for clang, but not today)

2) I spent considerable time to try to get the gcc marker comment to work, but nothing I tried worked! Some comment somewere suggested that in order for that to work one has to add -C to gcc arguments (meaning comments will be passed to cc1). Sure gcc 7 documentation doesn't mention anything about this requirement...

tomi
  • 153
  • 1
  • 4
  • 1
    For XCode 12 compatibility (along with GNU GCC >= 7 compatibility), I used a variation of your solution: `#if defined(__GNUC__) && __GNUC__ >= 7 || defined(__clang__) && __clang_major__ >= 12`. On XCode 12 `$ gcc -xc -dM -E /dev/null | sort | grep __GNUC__` yields `#define __GNUC__ 4`. – RjOllos Oct 27 '20 at 21:44
  • good information -- will integrate to my "templates" :D – tomi Nov 03 '20 at 22:03
  • 1
    Clang actually supports this since version 10 so `__clang_major__ >= 10` is more accurate. It seems this was missed in the release notes but the commit is here: https://github.com/llvm/llvm-project/commit/1e0affb6e564b7361b0aadb38805f26deff4ecfc – Deewiant May 27 '21 at 12:48
  • I tried with `__cland_major__>=10` and got the issue of "declaration does not declare anything" – Leonid Usov Jun 30 '21 at 17:39
1

You can also try the code below, because only this one works for me on Android:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
// your code
#pragma GCC diagnostic pop
Zhou Hongbo
  • 1,297
  • 13
  • 25