Как вы объясните, что строка 7 получает предупреждение, а не строка 5 или строка 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 при компиляции на 32-битной архитектуре (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]
Если это поможет вам понять мой вопрос, вот как я это вижу (возможно, неправильно!):
Я полагаю, что на 32-битные машинные операции выполняются над 32-битными числами. Поскольку unsigned char
вписывается в 32-битный int
, результатом операции будет 32-битный int
. Но поскольку GCC не выдает предупреждений в строках 5 и 6, я предполагаю, что происходит что-то еще:
строка 5:GCC вычисляет, что (uchar) ИЛИ (uchar) никогда не превышает MAX(uchar) , так что без предупреждения.
строка 6:GCC считает, что (uchar) AND 0xF никогда не больше, чем MAX(uchar), так что никаких предупреждений. Явный бросок даже не нужен.
строка 7:На основе предположений выше: И не должно выдавать предупреждения (начиная со строки 6), ИЛИ также не должно выдавать предупреждения (начиная с строки 5).
Я думаю, моя логика где-то ошибочна. Помогите понять логику компилятора.