public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated
@ 2022-03-16 8:42 coenraad at wish dot org.za
2022-03-16 8:44 ` [Bug c/104948] " coenraad at wish dot org.za
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: coenraad at wish dot org.za @ 2022-03-16 8:42 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
Bug ID: 104948
Summary: When '&&' present in a comparison, a warning should be
generated
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: coenraad at wish dot org.za
Target Milestone: ---
The sheer number of issues reported here that wrongly use '&&' as a logical
AND, warrants that this warning is direly necessary.
Even worse, the presence of '&&' in an evaluation, causes that branch to be
optimized out, completely, no matter what optimization level is used.
The reason for so many people using '&&' as logical AND, is because that is
what it is in almost every other language in widespread use.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
@ 2022-03-16 8:44 ` coenraad at wish dot org.za
2022-03-16 8:51 ` pinskia at gcc dot gnu.org
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: coenraad at wish dot org.za @ 2022-03-16 8:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #1 from dagelf <coenraad at wish dot org.za> ---
To boot, most other C compilers interpret `&&` as a logical AND.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
2022-03-16 8:44 ` [Bug c/104948] " coenraad at wish dot org.za
@ 2022-03-16 8:51 ` pinskia at gcc dot gnu.org
2022-03-16 9:07 ` coenraad at wish dot org.za
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-03-16 8:51 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |INVALID
Status|UNCONFIRMED |RESOLVED
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
unary operator vs binary operator.
You are just confused really.
that is if used as an unary operator, it will taken as the address of the
lable. While used as a binary operator it will be used as you expect.
Also the warning already happens with -Waddress (which is enabled with -Wall)"
<source>: In function 'f':
<source>:3:9: warning: the address of 'a' will always evaluate as 'true'
[-Waddress]
if (&&a) return 1;
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
2022-03-16 8:44 ` [Bug c/104948] " coenraad at wish dot org.za
2022-03-16 8:51 ` pinskia at gcc dot gnu.org
@ 2022-03-16 9:07 ` coenraad at wish dot org.za
2022-03-16 9:10 ` pinskia at gcc dot gnu.org
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: coenraad at wish dot org.za @ 2022-03-16 9:07 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #3 from dagelf <coenraad at wish dot org.za> ---
Can you please give me an example of code with the generated machine code where
it actually works as a logical AND?
Because I've tried several versions, and under no circumstances did it function
as a binary operator.
The warning might be improved to state that `&&` is not logical AND.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (2 preceding siblings ...)
2022-03-16 9:07 ` coenraad at wish dot org.za
@ 2022-03-16 9:10 ` pinskia at gcc dot gnu.org
2022-03-16 9:10 ` pinskia at gcc dot gnu.org
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-03-16 9:10 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to dagelf from comment #3)
> Can you please give me an example of code with the generated machine code
> where it actually works as a logical AND?
>
> Because I've tried several versions, and under no circumstances did it
> function as a binary operator.
>
> The warning might be improved to state that `&&` is not logical AND.
int f(int *a, int *b)
{
if (*a && *b)
return 1;
return 0;
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (3 preceding siblings ...)
2022-03-16 9:10 ` pinskia at gcc dot gnu.org
@ 2022-03-16 9:10 ` pinskia at gcc dot gnu.org
2022-03-16 9:13 ` rguenth at gcc dot gnu.org
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-03-16 9:10 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #4)
> (In reply to dagelf from comment #3)
> > Can you please give me an example of code with the generated machine code
> > where it actually works as a logical AND?
> >
> > Because I've tried several versions, and under no circumstances did it
> > function as a binary operator.
> >
> > The warning might be improved to state that `&&` is not logical AND.
>
> int f(int *a, int *b)
> {
> if (*a && *b)
> return 1;
> return 0;
> }
Note in C, && is short cutting that means *a != 0 has to be true before
evaluating *b != 0.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (4 preceding siblings ...)
2022-03-16 9:10 ` pinskia at gcc dot gnu.org
@ 2022-03-16 9:13 ` rguenth at gcc dot gnu.org
2022-03-16 9:33 ` redi at gcc dot gnu.org
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-03-16 9:13 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to dagelf from comment #3)
> Can you please give me an example of code with the generated machine code
> where it actually works as a logical AND?
>
> Because I've tried several versions, and under no circumstances did it
> function as a binary operator.
>
> The warning might be improved to state that `&&` is not logical AND.
Maybe you can provide one of the several versions where it does not work to
enlight us. Even the following works
int f(int a)
{
L:
if (a && && L)
return 1;
return 0;
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (5 preceding siblings ...)
2022-03-16 9:13 ` rguenth at gcc dot gnu.org
@ 2022-03-16 9:33 ` redi at gcc dot gnu.org
2022-03-16 11:20 ` coenraad at wish dot org.za
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-16 9:33 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Until you clear up your confusion, please stop leaving completely incorrect
comments all over bugzilla.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (6 preceding siblings ...)
2022-03-16 9:33 ` redi at gcc dot gnu.org
@ 2022-03-16 11:20 ` coenraad at wish dot org.za
2022-03-16 12:34 ` redi at gcc dot gnu.org
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: coenraad at wish dot org.za @ 2022-03-16 11:20 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #8 from dagelf <coenraad at wish dot org.za> ---
Makes perfect sense now. && is "logical" in that it can only produce a bool,
which in C is an int and anything except 0 or 1 is evaluated to false at
compile time.
There was a time when 'logical' and 'bitwise' were used interchangeably, based
on the fact that 'boolean operators' work on 'boolean logic'.
This is what lead me here:
$ cat test.c
int f(int a) {
if ((a && 12) == 12 )
return 11;
return 10;
}
$ gcc -c -O0 test.c && objdump -d test1.o
test1.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: b8 00 00 00 00 mov $0xa,%eax
c: 5d pop %rbp
d: c3 retq
With a single `&` it works as expected.
In my defence, when I last did a C course all boolean operators were bitwise. I
suddenly feel really old that even C has changed. Even the definition of
'logical' and 'bitwise' has changed.
Apologies for not testing the obvious '-Wall'.
Also apologies for just skimming over the output of icc, clang and msvc... I
just noticed that they include jumps where gcc didn't, so I was mistaken.
The optimizations are impressive.
Still, searching for the issues logged here with '&&' in an evaluation, does
point to the fact that the error message could be improved. Might I recommend
'non-bitwise boolean' in the message instead of just 'boolean'. Or even better,
add '(did you mean bitwise AND & instead of &&) if that's present.
$ gcc -Wall -c -O0 test.c
test1.c: In function ‘f’:
test1.c:5:22: warning: comparison of constant ‘12’ with boolean expression is
always false (Did you mean & instead of &&?) [-Wbool-compare]
Compare to "warning: comparison of constant ‘12’ with non-bitwise boolean
expression is always false [-Wbool-compare]" might lead to less confusion.
When expecting the result of an '&&' evaluation to be a bitwise AND, this
distinction can make a world of difference and could've pointed at least me in
the right direction.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (7 preceding siblings ...)
2022-03-16 11:20 ` coenraad at wish dot org.za
@ 2022-03-16 12:34 ` redi at gcc dot gnu.org
2022-03-16 12:40 ` jakub at gcc dot gnu.org
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-16 12:34 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to dagelf from comment #8)
> Makes perfect sense now. && is "logical" in that it can only produce a bool,
> which in C is an int and anything except 0 or 1 is evaluated to false at
> compile time.
No, in C bool is a distinct data type, and sizeof(bool) == 1.
Values of that type other than 0 or 1 result in undefined behaviour.
>
> There was a time when 'logical' and 'bitwise' were used interchangeably,
> based on the fact that 'boolean operators' work on 'boolean logic'.
>
> This is what lead me here:
>
> $ cat test.c
> int f(int a) {
> if ((a && 12) == 12 )
This will never be true.
The result of (a && 12) is either 0 or 1, and so never equal to 12.
> return 11;
> return 10;
> }
>
> $ gcc -c -O0 test.c && objdump -d test1.o
> test1.o: file format elf64-x86-64
> Disassembly of section .text:
> 0000000000000000 <f>:
> 0: 55 push %rbp
> 1: 48 89 e5 mov %rsp,%rbp
> 4: 89 7d fc mov %edi,-0x4(%rbp)
> 7: b8 00 00 00 00 mov $0xa,%eax
> c: 5d pop %rbp
> d: c3 retq
>
> With a single `&` it works as expected.
Your expectation is wrong.
>
> In my defence, when I last did a C course all boolean operators were
> bitwise.
I doubt that is true.
> I suddenly feel really old that even C has changed. Even the
> definition of 'logical' and 'bitwise' has changed.
I don't think that's true either.
> Compare to "warning: comparison of constant ‘12’ with non-bitwise boolean
> expression is always false [-Wbool-compare]" might lead to less confusion.
It would confuse people who know C, because "non-bitwise boolean expression" is
meaningless.
> When expecting the result of an '&&' evaluation to be a bitwise AND,
Your expectation is simply wrong, that's not how C works. We can't write
diagnostics to suit every potential misunderstanding of how C works.
The warning text is accurate and correct.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (8 preceding siblings ...)
2022-03-16 12:34 ` redi at gcc dot gnu.org
@ 2022-03-16 12:40 ` jakub at gcc dot gnu.org
2022-03-16 12:56 ` schwab@linux-m68k.org
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-03-16 12:40 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #9)
> (In reply to dagelf from comment #8)
> > Makes perfect sense now. && is "logical" in that it can only produce a bool,
> > which in C is an int and anything except 0 or 1 is evaluated to false at
> > compile time.
>
> No, in C bool is a distinct data type, and sizeof(bool) == 1.
_Bool, that is. bool is when stdbool.h is included a define to _Bool.
Though, && result is int in C, not _Bool, while in C++ bool.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (9 preceding siblings ...)
2022-03-16 12:40 ` jakub at gcc dot gnu.org
@ 2022-03-16 12:56 ` schwab@linux-m68k.org
2022-03-16 13:04 ` redi at gcc dot gnu.org
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: schwab@linux-m68k.org @ 2022-03-16 12:56 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #11 from Andreas Schwab <schwab@linux-m68k.org> ---
The size of bool is target dependent (though only Darwin/ppc overrides it).
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (10 preceding siblings ...)
2022-03-16 12:56 ` schwab@linux-m68k.org
@ 2022-03-16 13:04 ` redi at gcc dot gnu.org
2022-03-17 9:03 ` coenraad at wish dot org.za
2022-03-17 10:43 ` [Bug c/104948] When '&&' has non bool parameters, a better " redi at gcc dot gnu.org
13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-16 13:04 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Yes, to be more precise:
&& produces an int (not a _Bool / bool) with value 0 or 1.
_Bool (a.k.a bool) is a distinct type, which might be larger or smaller than
int (the only actual requirement is "large enough to store the values 0 and
1").
The name 'bool' is currently just a macro for _Bool defined in <stdbool.h> but
C23 might change it to a proper keyword:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2934.pdf
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' present in a comparison, a warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (11 preceding siblings ...)
2022-03-16 13:04 ` redi at gcc dot gnu.org
@ 2022-03-17 9:03 ` coenraad at wish dot org.za
2022-03-17 10:43 ` [Bug c/104948] When '&&' has non bool parameters, a better " redi at gcc dot gnu.org
13 siblings, 0 replies; 15+ messages in thread
From: coenraad at wish dot org.za @ 2022-03-17 9:03 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #13 from dagelf <coenraad at wish dot org.za> ---
Yes, I seem to have had a hole in my head. Sorry. For reference, to summarise
then:
& returns only the bits that are the same (bitwise AND) (or the bits that are
left after AND) (which will evaluate to true unless its 0 eg. (2 & 1) is false
but (3 & 1) is true.
&& casts operands to bool, so anything nonzero becomes 1. (eg. (2 && 1) is
true)
&& and & nonequivalence: https://godbolt.org/z/Yf5cxcKch
So & and && are only interchangeable when operating on bool parameters, on
anything else they each do something completely different.
The fact that there's a warning is great. Perhaps its fine. But this is
something so fundamental, it feels like no room for confusion should be left.
In fact, the more I think about it, the more I am convinced that it should not
be a warning, but an error, so -Werror is my new default.
Although I would love to find counter examples, I would be willing to wager
that && mixed with non bools, will almost always be done in error.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug c/104948] When '&&' has non bool parameters, a better warning should be generated
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
` (12 preceding siblings ...)
2022-03-17 9:03 ` coenraad at wish dot org.za
@ 2022-03-17 10:43 ` redi at gcc dot gnu.org
13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-17 10:43 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948
--- Comment #14 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to dagelf from comment #13)
> Although I would love to find counter examples, I would be willing to wager
> that && mixed with non bools, will almost always be done in error.
No, this is valid and not done in error:
void f(const char* str, size_t len)
{
if (str && len)
{ /* ... */ }
}
The condition is equivalent to (str != 0 && len != 0) but more succinct. If you
prefer the more verbose form, that's fine, but it doesn't mean everyone else's
code is erroneous.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2022-03-17 10:43 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-16 8:42 [Bug c/104948] New: When '&&' present in a comparison, a warning should be generated coenraad at wish dot org.za
2022-03-16 8:44 ` [Bug c/104948] " coenraad at wish dot org.za
2022-03-16 8:51 ` pinskia at gcc dot gnu.org
2022-03-16 9:07 ` coenraad at wish dot org.za
2022-03-16 9:10 ` pinskia at gcc dot gnu.org
2022-03-16 9:10 ` pinskia at gcc dot gnu.org
2022-03-16 9:13 ` rguenth at gcc dot gnu.org
2022-03-16 9:33 ` redi at gcc dot gnu.org
2022-03-16 11:20 ` coenraad at wish dot org.za
2022-03-16 12:34 ` redi at gcc dot gnu.org
2022-03-16 12:40 ` jakub at gcc dot gnu.org
2022-03-16 12:56 ` schwab@linux-m68k.org
2022-03-16 13:04 ` redi at gcc dot gnu.org
2022-03-17 9:03 ` coenraad at wish dot org.za
2022-03-17 10:43 ` [Bug c/104948] When '&&' has non bool parameters, a better " redi at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).