How to use __attribute__((fallthrough)) correctly in gcc
Asked Answered
D

3

10

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?

Dermoid answered 27/7, 2017 at 11:8 Comment(3)
If you compare the 6.4 documentation and the 7.1 documentation, it seems statement attributes like that was added in version 7.Horta
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 constraintAttica
@StoryTeller that makes senseDermoid
B
13

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;
}
Begga answered 9/2, 2018 at 9:26 Comment(4)
Both the marker comment or attribute can be use after the code on the same line, or below.Diverticulosis
Not without a warning. With the attribute warning: empty declaration will be returned on older GCC versions (< 7.x).Begga
Sorry, the GCC7 was implied.Diverticulosis
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.Gstring
P
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...

Progesterone answered 28/10, 2018 at 10:48 Comment(4)
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.Burgenland
good information -- will integrate to my "templates" :DProgesterone
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: github.com/llvm/llvm-project/commit/…Sprue
I tried with __cland_major__>=10 and got the issue of "declaration does not declare anything"Koren
B
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
Barbershop answered 15/6, 2022 at 9:37 Comment(1)
Ignoring all implicit fall-throughs isn't really the same as ignoring explicit fall-throughs. The whole idea of the attribute is to support a helpful diagnostic when you accidentally missed a break or similar.Jaine

© 2022 - 2024 — McMap. All rights reserved.