为什么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)
答案 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。