Re: check idea: warn when mixing signedness in ?: operator (got bitten by this recently)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 19, 2021 at 12:21:39PM +0200, Aurélien Aptel wrote:
> Hi,
> 
> If the <then> and <else> expression in the ?: ternary operator have
> different signedness they will both be implicitely casted to unsigned.
> 
> When the result is stored in a variable with a storage capable of
> holding both values, this is very unexpected. Consider this example:
> 
>     int rc = -1;
>     unsigned int foo = 123;
>     long x = y ? foo : rc;
> 
> If one of the branch of the ?: is unsigned, then the compiler will cast
> both branch to unsigned _before_ storing it in x. Despite long being
> able to store INT_MIN, INT_MAX, UINT_MAX (assuming 64b long/32b int).
> 
> So if y is 0, it's basically doing
> 
>     long x = (long)((unsigned int)-1);
> 
> Which will result in storing 0x00000000ffffffff (4294967295) instead of
> expected 0xffffffffffffffff (-1).

Hmmm,
I'm wondering what you would be warned about:
- about 'y ? foo : rc' becoming unsigned?
- about the cast 'unsigned int' -> '(signed) long' doing an zero-extension
  and not a sign extension?

In both cases, it's not very different than:
	int rc = -1;
	unsigned int foo = 0;
	long x = foo + rc;

and it boils down to the difference between:
	long x = (long)((unsigned int)-1);
and
	long x = (long)((int)-1);

> I thought we hit some sort of weird compiler bug but after reducing the
> problem to the simple example above and trying it GCC, clang, ICC and
> MSVC they all do the same thing: https://godbolt.org/z/P5Ts7o1df
> 
> So it is most likely a C quirk. Standard reads 6.5.15. 5)
> > If both the second and third operands have arithmetic type, the result
> > type that would be determined by the usual arithmetic conversions, were
> > they applied to those two operands, is the type of the result.

Yes, it' also what Sparse is doing.

Cheers,
-- Luc



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux