GCC Bugzilla – Bug 26298
-Wconversion fails to detect signedness change during widening conversion
Last modified: 2006-12-01 21:22:17 UTC
The following code gives two different results without any warning:
void toInt(int i)
fprintf(stderr, "i = %d\n", i);
void toLongLong(long long L)
fprintf(stderr, "L = %lld\n", L);
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).
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.
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." 
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  warns for the wrap-around as:
pr26298.c:15: warning: coercion as 'int' alters 'unsigned int' constant value
26167, the one I added in the dependencies
and what is your opinion about the rest of my comment?
Well, you are right. This bug is a dup of the bug requesting -Wcoercion (if we have such).
*** This bug has been marked as a duplicate of 26167 ***