2

I want clang to catch my inadvertent 'switch' statement fallthroughs. This shell script demonstrates my failure; I show the output after the script itself. What am I doing wrong?

#!/bin/sh

cat <<EOD > 1.c
#include <stdio.h>
int main(void)
{
  int etwas=5;
  switch(etwas)
  {
    case 5:
    {
      printf("It's 5.\n");
    }
    case 6:
    {
      printf("It's 6.\n");
    }
    default:
    {
      printf("It's something else\n");
      break;
    }
  }
  return 0;
}
EOD

rm -f 1
clang --version
echo === demonstrating that unrecognized warning names are not allowed ===
clang -Wnonsense-warning -Werror -Wall 1.c -o 1
echo === The real compile follows. ===
clang -Wimplicit-fallthrough 1.c -o 1
echo === The execution follows. ===
./1

The output:

FreeBSD clang version 4.0.0 (tags/RELEASE_400/final 297347) (based on LLVM 4.0.0)
Target: x86_64-unknown-freebsd11.1
Thread model: posix
InstalledDir: /usr/bin
=== demonstrating that unrecognized warning names are not allowed ===
error: unknown warning option '-Wnonsense-warning'
      [-Werror,-Wunknown-warning-option]
=== The real compile follows. ===
=== The execution follows. ===
It's 5.
It's 6.
It's something else
Bill Evans at Mariposa
  • 3,590
  • 1
  • 18
  • 22
  • what issue did you face? – user2736738 Feb 25 '18 at 19:01
  • What is your problem again? `-Wnonsense-warning` doesn't seem to be a clang option based on the output. – Pablo Feb 25 '18 at 19:12
  • @Pablo: The problem is not directly related to -Wnonsense-warning. I wanted to show that clang does indeed recognize -Wimplicit-fallthrough (rather than simply ignoring any warning it doesn't know about) by showing that clang complains about nonsense warning names. – Bill Evans at Mariposa Feb 25 '18 at 19:14
  • @Michi: I did that, no change in the output. On a lark, I substituted clang for GCC in that #pragma line. Still no change in the output. I guess I'm missing your point. – Bill Evans at Mariposa Feb 25 '18 at 19:19
  • What happens if you do: `-Wimplicit-fallthrough=3` ? – Michi Feb 25 '18 at 19:20
  • @coderredoc: The issue I faced was that I want the compiler to warn me that I implicitly fall through from one case to the next by inadvertently leaving out the 'break' statement, but the compiler is not issuing that warning. – Bill Evans at Mariposa Feb 25 '18 at 19:21
  • 1
    Strangely, I can't get clang to warn on the fall-through when compiling as C. If I change it to C++ it correctly warns, but only if I set it to [C++11](https://godbolt.org/g/2xFkFQ) [or later](https://godbolt.org/g/AQLjBP) ([C++03 doesn't warn](https://godbolt.org/g/5so1wg)). – Cornstalks Feb 25 '18 at 19:22
  • @michi: When using -Wimplicit-fallthrough=3 I get the same complaint as when I use -Wnonsense-warning -- unknown warning option. – Bill Evans at Mariposa Feb 25 '18 at 19:24
  • @BillEvansatMariposa I am not using CLANG, what standard version is used by default? – Michi Feb 25 '18 at 19:25
  • @Michi: I'm not sure what you mean by "by default", but the version I'm using is a stock FreeBSD clang (whose version is shown in the output above) installed when I installed FreeBSD 11.1-RELEASE. – Bill Evans at Mariposa Feb 25 '18 at 19:27
  • @BillEvansatMariposa I mean something [Like This](https://stackoverflow.com/questions/14737104/what-is-the-default-c-mode-for-the-current-gcc-especially-on-ubuntu) `GCC-7` uses `-std=gnu11` – Michi Feb 25 '18 at 19:30
  • 1
    I'm getting the same results as @Cornstalks (with Apple LLVM v9.0.0) -- compile with ``--std=c++11`` and the error appears. I suggest he converts his remark into an answer. – fork2execve Feb 25 '18 at 20:43
  • @Michi The value of __STDC_VERSION__ is 201112L, which if I'm to believe https://en.wikipedia.org/wiki/C11_%28C_standard_revision%29 is C11. (Unfortinately, the double underscore before and after STD_VERSION doesn't show when I post this comment.) – Bill Evans at Mariposa Feb 25 '18 at 21:02
  • put a `break;` statement at the end of every `case` code block. Note: it is syntactically correct to fall through into the next case (of course, you should insert a comment to that effect, so some reader of your code knows the missing 'break;` statement was on purpose. – user3629249 Feb 26 '18 at 10:46
  • @user3629249: Correct. But the thrust of my question was to find occurrences in the code where the `break` is missing. – Bill Evans at Mariposa Oct 10 '18 at 08:59

1 Answers1

2

Apparently, it is an intentional design decision that -Wimplicit-fallthrough should only take effect in C++11 mode (and not in C mode, or C++03).

The rationale expressed in the mailing list discussion appears to be something like:

  1. They don't want it enabled by default in C because it will annoy C coders, and (prior to C2x) there was no agreed-on way to indicate intentional fallthrough in the code;
  2. They do want it enabled in C++11 when -Wextra is specified, so they want -Wextra to imply -Wimplicit-fallthrough. But their front end doesn't support having -Wextra imply different options depending on whether we're in C++11 mode or not;
  3. The easiest way to achieve (1) and (2) is just to disable it entirely in C
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Ok, they don't want it enabled by default in C. Is there ANY way to enable it in C (using clang)? -Wextra -Wimplicit-fallthrough doesn't do that. – Bill Evans at Mariposa Feb 25 '18 at 21:27
  • 1
    @BillEvansatMariposa Not that I'm aware of ; clang devs do read SO though so maybe one of them will come along later and comment – M.M Feb 25 '18 at 21:37
  • FWIW `-std=c2x -Wimplicit-fallthrough` and `[[fallthrough]];` now work for C with clang – xyz Mar 08 '21 at 17:51