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;
}
32 ビット アーキテクチャ (Windows PC) でコンパイルした場合の GCC 4.6.2 出力:
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) OR (uchar) が MAX(uchar) よりも大きくなることはないと判断するため、警告はありません。
6 行目: GCC は、(uchar) AND 0xF が MAX(uchar) よりも大きくなることはないと判断するため、警告はありません。明示的なキャストは必要ありません。
7 行目:上記の仮定に基づく: AND は警告を出すべきではなく (6 行目以降)、OR も警告を出すべきではありません (5 行目以降)。
私の論理はどこかで間違っていると思います。コンパイラのロジックを理解するのを手伝ってください。