とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

VC++10 の<stdint.h>, <cstdint>はバグっている (4)

<追記>
このエントリは丸ごと間違っているかもしれません。みんな規格書を参照しよう…。
</追記>
<追追記>
規格書確認したけど,やっぱ間違ってる。このエントリの主張を撤回。
</追追記>
<追追追記>
VC++10 の<stdint.h>, <cstdint>はバグっている (4) へのツッコミ
</追追追記>

しつこいですが,Microsoft Visual C++ 2010 の , ヘッダにはまだバグがあります。
いくつかの INTN_C マクロがバグっています。これらのマクロは int_leastN_t 型の整数定数式に展開されなければなりませんが,VC++10はそうなっていません。
以下,バグ再現コード。

#include<cstdint>
#include<iostream>

void say_n(int_least8_t n){
 std::cout << "int_least8_t, " << static_cast<int>(n) << std::endl;
}
void say_n(int_least16_t n){std::cout << "int_least16_t, " << n << std::endl;}
void say_n(int_least32_t n){std::cout << "int_least32_t, " << n << std::endl;}
void say_n(int_least64_t n){std::cout << "int_least64_t, " << n << std::endl;}
void say_n(uint_least8_t n){std::cout << "uint_least8_t, " << n << std::endl;}
void say_n(uint_least16_t n){std::cout << "uint_least16_t, " << n << std::endl;}
void say_n(uint_least32_t n){std::cout << "uint_least32_t, " << n << std::endl;}
void say_n(uint_least64_t n){std::cout << "uint_least64_t, " << n << std::endl;}

int main(){
 say_n(INT8_C(0));
 say_n(INT16_C(0));
 say_n(INT32_C(0));
 say_n(INT64_C(0));
 say_n(UINT8_C(0));
 say_n(UINT16_C(0));
 say_n(UINT32_C(0));
 say_n(UINT64_C(0));
}

実行結果:

int_least32_t, 0
int_least32_t, 0
int_least32_t, 0
int_least64_t, 0
int_least32_t, 0
int_least32_t, 0
uint_least32_t, 0
uint_least64_t, 0

オーバーロード解決の結果を見ると,INT8_C, INT16_C, UINT8_C, UINT16_C マクロがバグっているのが分かります。あちゃー…。
元のソースは修正して,マクロ内部で適当な型でキャストするなどしなければなりませんね。