[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-17 Thread coenraad at wish dot org.za via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #13 from dagelf  ---
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.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #12 from Jonathan Wakely  ---
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  but
C23 might change it to a proper keyword:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2934.pdf

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread schwab--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #11 from Andreas Schwab  ---
The size of bool is target dependent (though only Darwin/ppc overrides it).

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #10 from Jakub Jelinek  ---
(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.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #9 from Jonathan Wakely  ---
(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:
>  :
>0: 55  push   %rbp
>1: 48 89 e5mov%rsp,%rbp
>4: 89 7d fcmov%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.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread coenraad at wish dot org.za via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #8 from dagelf  ---
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:
 :
   0:   55  push   %rbp
   1:   48 89 e5mov%rsp,%rbp
   4:   89 7d fcmov%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.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #7 from Jonathan Wakely  ---
Until you clear up your confusion, please stop leaving completely incorrect
comments all over bugzilla.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #6 from Richard Biener  ---
(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;
}

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #5 from Andrew Pinski  ---
(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.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #4 from Andrew Pinski  ---
(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;
}

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread coenraad at wish dot org.za via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #3 from dagelf  ---
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.

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

Andrew Pinski  changed:

   What|Removed |Added

 Resolution|--- |INVALID
 Status|UNCONFIRMED |RESOLVED

--- Comment #2 from Andrew Pinski  ---
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)"
: In function 'f':
:3:9: warning: the address of 'a' will always evaluate as 'true'
[-Waddress]
 if (&) return 1;

[Bug c/104948] When '&&' present in a comparison, a warning should be generated

2022-03-16 Thread coenraad at wish dot org.za via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104948

--- Comment #1 from dagelf  ---
To boot, most other C compilers interpret `&&` as a logical AND.