間違った出力を返す C ライブラリ関数 strtoull の問題に直面しています。
int main(int argc, char *argv[])
{
unsigned long long int intValue;
if(atoi(argv[2]) == 1)
{
intValue = strtoull((const char *)argv[1], 0, 10 );
}
else
{
// ...
}
printf("intValue of %s is %llu \n", argv[1], intValue);
return 0;
}
それらをビルドし、32 ビットおよび 64 ビットの実行可能ファイルを str32_new および str64_new として生成しました。しかし、32 ビットの exe から受け取った出力は、間違った番号が返されるためエラーになります。
strtoull は、渡された文字列「5368709120」に対して番号 5368709120 を返すはずでしたが、1073741824 を返しました。
# ./str32_new "5368709120" 1
intValue of 5368709120 is 1073741824
文字列から1文字減らすと、適切な出力が表示されることに注意してください。
# ./str32_new "536870912" 1
intValue of 536870912 is 536870912
32ビットexeに添付されたglibcは
# readelf -Wa /home/str32_new | grep strt
[39] .shstrtab STRTAB 00000000 002545 000190 00 0 0 1
[41] .strtab STRTAB 00000000 0032f8 0002a4 00 0 0 1
0804a014 00000607 R_386_JUMP_SLOT 00000000 strtoull
6: 00000000 0 FUNC GLOBAL DEFAULT UND strtoull@GLIBC_2.0 (2)
55: 00000000 0 FILE LOCAL DEFAULT ABS strtoull.c
75: 00000000 0 FUNC GLOBAL DEFAULT UND strtoull@@GLIBC_2.0
77: 08048534 915 FUNC GLOBAL DEFAULT 15 my_strtoull
64ビットexeに添付されたglibcは
# readelf -Wa /home/str64_new | grep strt
[39] .shstrtab STRTAB 0000000000000000 001893 000192 00 0 0 1
[41] .strtab STRTAB 0000000000000000 002cd0 00029b 00 0 0 1
0000000000601028 0000000700000007 R_X86_64_JUMP_SLOT 0000000000000000 strtoull + 0
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtoull@GLIBC_2.2.5 (2)
57: 0000000000000000 0 FILE LOCAL DEFAULT ABS strtoull.c
73: 00000000004006cc 804 FUNC GLOBAL DEFAULT 15 my_strtoull
82: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtoull@@GLIBC_2.2.5
64 ビット exe は適切な出力を示しますが、一部のシステムでは異常な動作をします。32 ビット exe の strtoull がそのように動作するのはなぜですか? また、この問題を解決するにはどうすればよいですか?