无符号字符在函数调用中自动提升为int,为什么?

时间:2013-02-07 07:26:49

标签: c++

为什么unsigned char在调用函数时会自动提升为int?在下面的示例中,有f(int)f(char)函数。似乎更合乎逻辑的是,编译器会强制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 个答案:

答案 0 :(得分:12)

unsigned char无法表示char。例如,如果它们都是8位,并且unsigned char包含值255,则会溢出signed char - 并且有符号整数溢出会调用未定义的行为。无论如何,通常希望可打印字符存储在char而不是unsigned char中(C字符串的类型为char[]而不是unsigned char[]等。)

因此,有必要向int进行宣传,以表示大于1 << (CHAR_BIT - 1)的值。

答案 1 :(得分:7)

我认为标准的正确推导是基于下面的段落,可以找到第13.3.3节最佳可行函数,即它是函数重载决策(非常复杂)规则的一部分

  

(§13.3.3.2/ 4)标准转换序列按其等级排序:完全匹配是一种比促销更好的转换,这是一种比转换更好的转换。除非符合以下规则之一,否则具有相同等级的两个转换序列是无法区分的:[...]

unsigned char转换为int归类为 promotion (在§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),并且,如上所述,在重载解析期间,促销优先于转换。

答案 2 :(得分:3)

在C ++标准中,char未定义为无符号或有符号(尽管大小为1字节),因此它的实现已定义。所以在你的实现中我相信它的签名字符就是它升级的原因。

答案 3 :(得分:-1)

int和char在C和C ++中的范围不同,如果char的范围是0到255,如果是int,它的范围是65535(int的范围将随OS而变化)。所以编译器只是把它当作int。