Предупреждение о преобразовании типов после побитовых операций в C

Как вы объясните, что строка 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).

Я думаю, моя логика где-то ошибочна. Помогите понять логику компилятора.

11
задан Alex 29 September 2015 в 07:01
поделиться