次のコードを検討してください。
$ cat o.c
#include <stdio.h>
#include <limits.h>
int absolute(int i) {
int j = i < 0 ? -i : i;
if (j<0) /* This is line 6 */
return 0;
return j;
}
int main() {
int i = 1;
printf("%d %d\n", i, absolute(i));
return 0;
}
でコンパイルすると-O2
、-Wstrict-overflow
警告が生成されます。
$ gcc -O2 -Wall -Wextra -Wstrict-overflow o.c
o.c: In function ‘absolute’:
o.c:6:6: warning: assuming signed overflow does not occur when simplifying comparison of absolute value and zero [-Wstrict-overflow]
ここで、上記のコードと機能的に同等と思われる次のコードを検討してください。
$ cat p.c
#include <stdio.h>
#include <limits.h>
int main() {
int i = 1;
int j = i < 0 ? -i : i;
if (j<0) // Changing i to INT_MIN above and changing (j<0) to (j>INT_MAX)
// doesn't change the behavior
j=0;
printf("%d %d\n", i, j);
return 0;
}
これを同じオプションでコンパイルしても、警告は発生しません。
$ gcc -O2 -Wall -Wextra -Wstrict-overflow p.c
$
2 番目のコードでコメントされているように、割り当てを to に変更しi=INT_MIN;
、条件を toに変更し(j>INT_MAX)
ても、警告は表示されません。
Ubuntu で gcc 4.7.2 を使用しています。
$ gcc --version
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
2つのケースの違いを理解できません。最適化と関係がありますか、それとも gcc がここで正しく動作していませんか?