10

タイプを対応する署名付きに変換するadd_signedMPLクラスのテストをいくつか開発しています。これは次のように定義されます。

template<class T>
struct add_signed { 
    typedef T type;
};

template<>
struct add_signed<std::uint8_t> { 
    typedef std::int8_t type;
};

template<>
struct add_signed<std::uint16_t> { 
    typedef std::int16_t type;
};

template<>
struct add_signed<std::uint32_t> { 
    typedef std::int32_t type;
};

template<>
struct add_signed<std::uint64_t> { 
    typedef std::int64_t type;
};

さまざまなタイプでテストしているときに、次のことが真であると評価されることに気付きました。

std::is_same<add_signed<uintptr_t>::type, intptr_t>::value  // true

同様に、add_unsigned MPLクラスの場合、次のコードはtrueと評価されます。

std::is_same<add_unsigned<intptr_t>::type, uintptr_t>::value  // true

私のコンパイラはMSVC2010です。

したがって、問題は、すべての(正常な)コンパイラでintptr_tに署名するとuintptr_tが生成され、その逆も同様であると想定できますか?

4

1 に答える 1

19

タイプintptr_tuintptr_tはISO/IEC 9899:1999(C99)ではオプションですが、一方が実装されている場合はもう一方も実装されています。すべての署名されたタイプには、同じサイズの署名されていない対応物があり、その逆も同様です。

§7.18.1整数型

イニシャルの有無のみが異なるtypedef名uを定義する場合、6.2.5で説明されているように、対応する符号付き型と符号なし型を示すものとします。これらの対応するタイプの1つを提供する実装は、他のタイプも提供するものとします。

..。

§7.18.1.4オブジェクトポインタを保持できる整数型

次の型は、voidへの有効なポインタをこの型に変換してから、voidへのポインタに戻すことができるというプロパティを持つ符号付き整数型を指定し、結果は元のポインタと同じになります。

intptr_t

次の型は、voidへの有効なポインタをこの型に変換してから、voidへのポインタに戻すことができるというプロパティを持つ符号なし整数型を指定し、結果は元のポインタと同じになります。

 uintptr_t

これらのタイプはオプションです。

C標準の意味では、関数はオブジェクトではないことに注意してください。uintptr_t関数ポインタを保持できるC標準では保証されていません。

幸いなことに、POSIXは救済策を講じています。オブジェクトポインタと関数ポインタが同じサイズである必要があります。

2.12.3ポインタータイプ

すべての関数ポインタ型は、への型ポインタと同じ表現を持つ必要がありますvoid。関数ポインタをへの変換はvoid *、表現を変更してはならない。void *このような変換の結果の値は、情報を失うことなく、明示的なキャストを使用して元の関数ポインター型に変換して戻すことができます。

ノート:

ISO C規格ではこれは必要ありませんが、POSIX準拠には必要です。

于 2012-05-01T13:47:10.023 に答える