LoginSignup
8
7

More than 5 years have passed since last update.

[MSVC 2005] printf系で64Bit型整数に気をつけよう

Last updated at Posted at 2014-08-12

小ネタです。

Visual C++2005でunsigned long long などの64bitな値をprintf系関数やcstring::formatで書式化すると妙なことになる場合があったので、バッドノウハウとしてメモしておきます。

例えば、下のようなコードがあったとします。


void testmain()
{
    unsigned long long vv = 0x0000000012345678ULL;
    unsigned long long uu = 0x0000000000000000ULL;

    printf("%x,%x,%s,%s\n",vv,uu,"test","words");
}

普通ですと、12345678,0,test,wordsと表示されるのですが、MSVCでは12345678,0,(null),(null)というふうに後ろの可変長引数がすっ飛ばされてしまいます。

なお、gccの場合は普通に表示されます。
(ただし、コンパイル時に親切にも警告を出力されます)

また、vvの値を0xFFFFFFFF00000000などの本当に64Bit値をもたせると、MSVCでは実行時エラーとなり、gccでは上位32Bitが切られて表示されます。
(これはgccの動作が正しいですね)

なお、このように書式文字列に%xを指定するのではなくて%llxとするとちゃんと表示できます。


void testmain()
{
    unsigned long long vv = 0x0000000012345678ULL;
    unsigned long long uu = 0x0000000000000000ULL;

    printf("%llx,%llx,%s,%s\n",vv,uu,"test","words");
}

つまりこれは%x指定では、ライブラリは数値の長さを分からずにすっ飛ばしてしまうということで問題が出てしまったのかもしれません。
(gccみたいに警告を出してくれるといいのですけどね)

あと、STLでお馴染みの<<系で出力すれば問題なく出力出来ました。


void testmain()
{
    unsigned long long vv = 0x0000000012345678ULL;
    unsigned long long uu = 0x0000000000000000ULL;

    cout << hex;
    cout << vv << "," << uu << "," << "test" << "," << "words" << endl;
}

ということで、64Bit整数を扱う場合は書式文字列に気をつけましょうということで...

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7