Bug 26298 - -Wconversion fails to detect signedness change during widening conversion
Summary: -Wconversion fails to detect signedness change during widening conversion
Status: RESOLVED DUPLICATE of bug 26167
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.3
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on: 26167
Blocks:
  Show dependency treegraph
 
Reported: 2006-02-15 09:10 UTC by Michael Becker
Modified: 2006-12-01 21:22 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-15 10:36:07


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Becker 2006-02-15 09:10:39 UTC
The following code gives two different results without any warning:

#include <stdio.h>

void toInt(int i)
{
  fprintf(stderr, "i = %d\n", i);
}

void toLongLong(long long L)
{
  fprintf(stderr, "L = %lld\n", L);
}

int main()
{
  toInt(-sizeof(int));
  toLongLong(-sizeof(int));

  return 0;
}

There should at least be a warning.
This behaviour can be found on SUN and on Linux x86 with compiler versions between 3.4.4 and 4.0.3 (prerelease).
Comment 1 Richard Biener 2006-02-15 10:36:07 UTC
With -Wconversion you get

t.c:5: warning: passing argument 1 of ‘toLongLong’ with different width due to prototype

though -Wconversion is neither in -Wall nor -Wextra.  I see you filed against
C++, which doesn't warn here, but we have a bug for a similar case already.

Also the C diagnostic could be improved in the case of a widening sign conversion,
because that is more likely an error than a non-widening sign conversion.
Comment 2 Manuel López-Ibáñez 2006-09-16 01:38:08 UTC
Richard, could you tell which bug report do you mean?

The -Wconversion warnings does not apply to this case. Wconversion warns about the effect of adding a prototype, not about sign conversions. 

Anyway, I still don't understand where is the bug. Unary minus applied to unsigned (what typically is the type of sizeof()) gives:

" `2^n - i', where `n' is the number of bits in the
unsigned type." [1]

So actually -sizeof(int) is 4294967292 (assuming sizeof(int) is 4). This number fits well in a signed long long. However, it doesn't fit in a signed int, and thus, it wraps around and produces -4.

The -Wcoercion flag provided by the Wcoercion project [2] warns for the wrap-around as:

pr26298.c:15: warning: coercion as 'int' alters 'unsigned int' constant value


[1] http://gcc.gnu.org/ml/gcc/1999-06n/msg00754.html
[2] http://gcc.gnu.org/wiki/Wcoercion


Comment 3 Richard Biener 2006-09-16 17:08:20 UTC
26167, the one I added in the dependencies
Comment 4 Manuel López-Ibáñez 2006-09-16 19:45:13 UTC
Richard,

and what is your opinion about the rest of my comment?
Comment 5 Richard Biener 2006-09-17 21:02:45 UTC
Well, you are right.  This bug is a dup of the bug requesting -Wcoercion (if we have such).
Comment 6 Dirk Mueller 2006-10-16 15:37:40 UTC

*** This bug has been marked as a duplicate of 26167 ***