5

Given following C code:

#include <stdbool.h>

int main (void)
{
    true;
    return 0;
}

I expect that -Wunused-value would cause a warning at line 5: true;
because this statement does nothing and can be a source of the bug
but it goes through silent - in fact -Wunused -Wall -Wextra does not catch it.


For comparison, something like this:

#define TRUE 1

int main (void)
{
    TRUE;
    return 0;
}

or this:

int main (void)
{
    1;
    return 0;
}

would trigger the proper warning as one would expect (GCC 14.2):

<source>: In function 'main':
<source>:3:5: warning: statement with no effect [-Wunused-value]
    3 |     1;
      |     ^

So I started digging; I thought this might be a regression in GCC.
I went from GCC 14.2 down to the very, very old releases
and seems like GCC 3.4.6 was the last one where the warning appears as expected.

I thought about reporting this to GCC but then I checked Clang
and Clang also does not produce any warning about this since Clang 3.0.0

See: https://godbolt.org/z/T361d3ad6


Although I was able to find similar bugs on GCC mailing list, e.g.
https://gcc.gnu.org/pipermail/gcc-bugs/2021-November/765405.html
I cannot believe that two major compiler vendors simply have the same bug for a long time.

I suspect this is happening since true is a macro defined inside of libc headers
and compiler generally do not yell about issues coming from libc
but since this one is happening inside of my code I'm a bit concerned.
I wasted a lot of time on finding this, then realizing the warning should catch it.


Is there any rationale on why this is happening?
Or is this just a bug/regression in the compiler that should be reported?


EDITs / NOTEs:

  • MSVC invoked with /Wall /std:c11 does NOT have this issue
  • Since I already have a lot of information, I reported this to LLVM/clang (seems like the easiest place to report it for now) - https://github.com/llvm/llvm-project/issues/106867
  • If I won't get any response on the bug above, I will send it to GCC
  • I do NOT believe that -Wsystem-header is a valid solution for this problem (see my comments under dbush answer for explanation)
2
  • 2
    You get the same effect for any macro in a system header (e.g. UINT8_MAX). Warnings are suppressed inside (substituted) macros in system headers and it seems that includes the result of the expression produced by the macro substitution (whether or not that is a good idea). Commented Aug 31, 2024 at 14:19
  • 1
    Also, instead of two compilers coming independently to the same behavior, it is likely that Clang copied the behavior of GCC. It generally intents to be compatible with GCC. Commented Aug 31, 2024 at 14:22

2 Answers 2

2

The warning doesn't show up because the macro true is defined in a system header, and warnings for constructs found in system headers are typically suppressed.

If you add the -Wsystem-headers flag, you'll see a warning.

Reference: https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Warning-Options.html#index-Wsystem-headers

Sign up to request clarification or add additional context in comments.

5 Comments

Yes, it apparently does - but -Wsystem-headers does not seem like something that should be required. According to GCC manual, this option should Print warning messages for constructs found in system header files., not in the user's code. In fact, if I use this with -Werror, it won't be possible to compile anything that uses libc. So I don't believe this is a proper solution. Although, it works fine in this case, It's not possible to use in real world scenario (unless I don't know something, please correct me if that's the case). Thanks for the answer though!
I added the link reference to GCC manual to your Answer @dbush Could you accept it? Reference: gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/…
Gonna write this once again, because I don't think my first comment was clear: Macro #define true 1 comes from libc header, but statement true; is a "construct" inside of user's code, NOT inside libc header, so -Wsystem-headers should NOT be required in order to catch it. This is how I understand it based on GCC Manual, unless I misunderstand what the "construct" means here.
also I just found out that while -Wsystem-headers fixes this for gcc, it does not work for clang and icx, at least not on my side (despite that both those compilers support said flag)
The wording of this answer suggests the behavior is intentional. However, I think it clearly contradicts the plain meaning of the documented behavior of -Wsystem-headers (since the code in question is not in any system header; it merely uses a symbol that is defined in a system header, which is hardly unusual for user code), and the discussion in GCC bug 77299 confirms that the GCC devs see it as a bug too.
0

This is GCC's bug.
Several tickets describe this behavior as undesired:

-Wsystem-headers should not be required in this case, as diagnosed construct occurs inside of user's code, not in system header. The macro itself comes from system header, but it is not expanded there.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.