How do you explain that line 7 gets a warning, but not line 5 or line 6?
int main() { unsigned char a = 0xFF; unsigned char b = 0xFF; a = a | b; // 5: (no warning) a = (unsigned char)(b & 0xF); // 6: (no warning) a = a | (unsigned char)(b & 0xF); // 7: (warning) return 0; } GCC 4.6.2 output when compiled on 32-bit architecture (Windows PC):
gcc -c main.c --std=c89 -Wall -Wextra -Wconversion -pedantic main.c: In function 'main': main.c:7:11: warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion] If this helps you understand my question, here is how I see this (probably incorrect!):
I suppose that on a 32-bit machine operations are done on 32-bit numbers. Since unsigned char fits into 32-bit int, the operation result is 32-bit int. But since GCC doesn't give warnings on lines 5 and 6, I guess there is something else going on:
line 5: GCC figures that (uchar) OR (uchar) is never bigger than MAX(uchar), so no warning.
line 6: GCC figures that (uchar) AND 0xF is never bigger than MAX(uchar), so no warning. Explicit cast is not even necessary.
line 7: Based on assumptions above: AND should not give warning (since line 6), OR should not give warning either (since line 5).
I guess my logic is faulty somewhere there. Help me understand the logic of the compiler.
Why does Wconversion emit a warning in an implicit conversion between variables even when it is known at compile time that the value does not change?:Warning because there is no flow control in front-ends (so we don't know the value of d).