-
Notifications
You must be signed in to change notification settings - Fork 626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implicit fallthroughs #568
Comments
The code has to be ANSI-C, aka ISO-C90 aka C89. It is expected that the code will be compiled with "-ansi" (or equivalent) and compiling without this, while it typically works, is not supported. So far as testing is concerned "-pedantic" should be used too. The code is tested with -Wimplicit-fallthrough with GCC and so far as warnings are concerned GCC really is the only supported compiler; obviously warnings that correspond to real bugs are valid from any compiler but trying to kill warnings in all compilers is impossible because they end up demanding different things. The compiler flags when testing with GCC are "-Wall -Wextra -Werror", there is configure support for -Werror (because configure fails if -Werror is set; use --enable-werror). Note that those settings are not set by default. This is because different versions of GCC have different warnings and new versions often have gratuitous additions that get removed PDQ. clang 18.1.8 -ansi (I think that is pretty much the latest version) does not warn about implicit-fallthrough even with -Wall and -Wextra An explicit -Wimplicit-fallthrough is required and even then it's just a warning (unless -Werror is given of course). With '-Wall -Wextra -std=c89 -pedantic" neither GCC nor clang warn. GCC does check for implicit fallthrough - I deleted line 3333 from pngfix.c and got the warning. So clang has removed -Wimplicit-fallthrough from -Wall - Wextra; presumably they got too many bugs about not recognizing the comment! Perhaps they should fix that :-) I really don't like the idea of replacing a safe, innocuous, comment with a mess of preprocessor. It's replacing something that works (with GCC at least) and is 100% safe with something that will require continuous maintenance to remove a warning that clang have already disabled themselves! It achieves nothing because GCC -Wall -Wextra -Werror already ensures that the build fails if there is an implicit fall-through. |
Thanks, @jbowler. I'm afraid I'm stuck using LLVM-15 (and greater) with It'd be swell if the fallthrough protections were cross-compiler compatible and it feels as though the machinery to do that (introduction of a preprocessor macro) isn't too bad (other projects, such as sqlite use it). I can understand if you feel otherwise, though, and appreciate that you're already using |
That would be [[fallthrough]]; It's part of the 2023 standard: https://en.cppreference.com/w/c/language/attributes/fallthrough but before that there was no standard. This is certainly an @ctruta thing; the GCC comment hack was always a comment hack and can't be implemented in any way that is even vaguely C90 compliant (or, indeed, anything until C23). The problem is that the hack is in the preprocessor, not the compiler, so that comment should always have disappeared into a space before the compiler gets invoked. I haven't tested to see whether |
work. We're already using |
In fact [[fallthrough]] works with gcc with all --std versions so far as I can see. The trick is:
This is completely compliant ANSI-C code which happens to work in GCC even if --std is defined to be less than 2023. The only issue for @ctruta is that -pedantic without --std=c23 reports, erroneously, that [[fallthrough]] is a C23 feature. I.e. the earlier --std versions do, in fact, "define" __has_c_attribute even with -pedantic and do, in fact, enable [[fallthrough]]; that's a clear GCC bug. Some explanation: C23 added __has_c_attribute which has, in fact, some very weird behavior. GCC supports it even if --std=!c23 and, the bug, even if -pendantic. |
Sqlite uses this:
Not sure if that's helpful or not. |
The word of god is in the standard (which I cannot afford to purchase) but cppreference.com (which I trust) says this: https://en.cppreference.com/w/c/language/attributes The relevant quote is:
So what sqlite is doing is not standard (it only works with GCC variants, which include clang and, IRC, ARM Ltd's native compiler). No doubt sqlite might fix this in the future by checking for the C23 defined "has_**c_**attribute". A mess of twisty little #ifdefs all alike. Phlugh. In my own code I'm just going for C23. I don't see any value in writing complex tests for diagnostics in out-of-date compilers; support, maybe (but I only support C99 and, maybe C11 or better) but diagnostics? So my current approach is to, yes, use a #define for "fallthrough" (et al.) but only define it when it is not previously defined; so this "works" because someone who must can do a -D on the command line (or in CFLAGS) and those who don't just get a warning. The libpng approach is radically different; it tries to do everything for everyone and that's a problem :-) |
@jbowler - In order to provide some more meat for us to discuss this, I've put up #572, which adds an appropriate macro and the accompanying warning flag to CMakeLists.txt. Compiling that code doesn't reveal any unannotated fallthroughs (nice!), at least for whatever set of macros the system set me up with. |
LLVM 15 with
-Wimplicit-fallthrough
enabled refuses to compile libpng because there are implicit fallthroughs.Some of these, such as those in
pngread.c
are commented. Others might not be (I'm still iterating).[[fallthrough]]
is part of C23 and__attribute__((fallthrough))
is available now to explicit mark fallthroughs in a way that's unambiguous to compilers.Would it be alright if I put up a PR introducing a cross-compiler compatible
INTENTIONAL_FALLTHROUGH
macro?The text was updated successfully, but these errors were encountered: