13

関数を呼び出すときにunsigned char自動的ににプロモートされるのはなぜですか?int以下の例では、f(int)f(char)関数があります。ビット数が同じであるため、コンパイラがaへのunsigned char引数を強制しcharて呼び出す方が論理的であるように思われました。代わりに、より多くのビットを持つ型に引数をプロモートすることを意味する場合でも、f(char)呼び出しています。f(int)ルールが定義されている場所へのポインタはありますか?標準またはコンパイラ/プラットフォーム固有ですか?

#include <iostream>

void f( int key )
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void f( char key )
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main( int argc, char* argv[] )
{
    int a = 'a';
    char b = 'b';
    unsigned char c = 'c';

    f(a);
    f(b);
    f(c);

    return 0;
}

この出力を生成します:

void f(int)
void f(char)
void f(int)
4

4 に答える 4

12

で表せunsigned charないからcharです。たとえば、どちらも 8 ビットで、 unsigned char に value が含まれている場合255、 - がオーバーフローし、符号signed char付き整数のオーバーフローが未定義の動作を引き起こします。charとにかく、印刷可能な文字は一般に、に格納され、格納されないことが期待されますunsigned char(また、C 文字列は型char[]であり、notunsigned char[]などです)。

intしたがって、より大きい値を表すには、 への昇格が必要です1 << (CHAR_BIT - 1)

于 2013-02-07T07:31:38.870 に答える
7

標準からの正しい派生は、セクション 13.3.3 Best viable functionsにある以下の段落に基づいていると思います。つまり、関数オーバーロード解決の (非常に複雑な) ルールの一部です。

(§13.3.3.2/4) 標準のコンバージョン シーケンスはランク順に並べられています。完全一致はプロモーションよりも優れたコンバージョンであり、プロモーションはコンバージョンよりも優れたコンバージョンです。次のルールのいずれかが適用されない限り、同じランクの 2 つの変換シーケンスは区別できません。[...]

unsigned charへの変換はプロモーションintとして分類されます (§4.5 で定義されています。以下を読むときは、それが整数型であることに注意してください)。(unsigned) char

§4.5 インテグラル プロモーション
[...]

(§4.5/2) bool、char16_t、char32_t、または wchar_t 以外の整数型の prvalue で、整数変換ランク (4.13) が int のランクよりも小さいものは、int がすべてを表すことができる場合、int 型の prvalue に変換できます。ソースタイプの値; それ以外の場合は、ソースの prvalue を unsigned int 型の prvalue に変換できます。

unsigned charへの変換は、ランクが同じであるため、昇進charには分類されません。

(§4.13/1) [...] char のランクは、signed char および unsigned char のランクと等しくなければなりません。[...]

代わりに整数変換(§4.7)として分類され、前述のように、オーバーロードの解決中は変換よりも昇格が優先されます。

于 2013-02-07T07:59:43.790 に答える
3

C++ 標準でcharは、 unsigned または signed (サイズは 1 バイトですが) とは定義されていないため、実装定義です。したがって、あなたの実装では、署名された char であると信じているため、昇格しました。

于 2013-02-07T08:49:31.040 に答える
-1

intとcharは、CとC ++では範囲が異なります。charの場合は0〜255の範囲で、intの場合は65535のようになります(intの範囲はOSによって異なります)。したがって、コンパイラはそれをintとして扱います。

于 2013-02-07T07:36:54.703 に答える