C : sizeof returns unsigned
見つけにくいバグ
以下のCodeを見てください。
さて、なんと表示されるでしょうか?
答えは、"100"ではなく、"0"になります。
#include <stdio.h>
#include <stdlib.h>
int array[] = {12, 23, 45, 67, 89};
#define TOTAL_ELEMENTS sizeof(array)/sizeof(array[0])
int main() {
int d = -1;
int x = 0;
if(d <= TOTAL_ELEMENTS){
x = 100;
}
printf("%d\n", x);
return 0;
}
マクロ定義、TOTAL_ELEMENTSは、unsigned intになります。なぜなら、sizeof演算子の結果は、unsignedなので。
if分の中身は、signedとunsignedの比較になり、unsignedに格上げされてから比較がなされます。すると、"-1"は、最大の正の値になるので、条件式は、偽となるのです。
このバグは、
#define TOTAL_ELEMENTS (int)(sizeof(array)/sizeof(array[0]))
とすることで修正できます。
Editor's note
不必要にunsigned型を使って、無用の複雑さを持ち込まないようにしましょう。「表現する値が、負になることはない」と言う理由だけで、unsignedを使わないこと。intのような、符号付きの型を使えば、複数の型を混在させた時の「格上げ」の規則に煩わされずに済みます。に済みます。
unsigned型を使うのは、ビットフィールドやバイナリマスクだけに限っても良い。
また、式にキャストをかけて、全オペランドを符号付き or 符号なし に統一すれば、コンパイラは結果の型を作り出さずに済みます。
いいなと思ったら応援しよう!
もしよろしければ、サポートをお願いします!
頂いたサポートは、Creatorとしての活動費に充てさせて頂きます。