是否在未指定的 signed 和 unsigned int 之间解析 char?
Is resolving char between signed and unsigned int unspecified?
据我了解,char
可能有不同的基础类型,具体取决于体系结构。
在隐式转换期间,unsigned char
可能变成 int
或 unsigned int
。
这是否意味着以下代码具有未指定的行为?
#include <iostream>
void function(unsigned int){
std::cout << "unsigned\n";
}
void function(int){
std::cout << "signed\n";
}
int main() {
char c;
function(c);
}
我没有收到任何编译器警告。它会始终解析为 "signed" 吗?
这只是一种 C++ 特性,称为 "Implicit type conversion/automatic type conversion/coercion"。当您将 char 传递给函数时,char 会隐式转换为 signed int。就像代码 "int a = 'C';" 你可以从这里了解更多关于强制转换的信息:http://www.learncpp.com/cpp-tutorial/44-implicit-type-conversion-coercion/
在幕后,所有类型都表示为二进制数,因此类型只是编译解释的一种方式。上面没有你说的这种机制
您的图表对于 整数提升 的情况是正确的。但是,在代码 function(c)
中,不会发生整数提升。这实际上是过载分辨率。如果只有一个 function
,则 c
被 转换 (未提升)为参数类型,以参数类型为准。
在重载决议的规则中,如果参数可以通过整数提升来匹配参数,那么该函数将被认为比另一个函数更匹配整数转换 需要匹配。
请参阅 C++14 中的 Table 12(第 13.3.3.1.2 节的一部分),其中列出了用于重载解析的隐式转换序列的等级。
因此您的代码示例将在具有 CHAR_MAX > INT_MAX
的系统上调用 function(unsigned int)
。
但是类型的大小是实现定义的,而不是未指定。
A char
几乎总是会转换为 int
。每当 sizeof(int) > sizeof(char)
然后 char
将被提升为 int
无论它是有符号的还是无符号的,就像你说的 int
可以容纳 [=10= 的整个范围].
你唯一能得到 unsigned int
的时间是 sizeof(char) == sizeof(int)
。在这种情况下,如果 char
是无符号的,那么它将被转换为 unsigned int
,因为 int
将无法保存整个值范围。
这可能会发生,因为标准仅规定 int
必须至少具有与 char
一样多的存储空间,因此可能存在一些具有 32 位字节的系统并且它们使 char
和 int
大小相同。
所以这是实现定义的行为,因为您需要知道实现定义的两种类型的大小和实现定义的 char
签名才能知道会发生什么。
据我了解,char
可能有不同的基础类型,具体取决于体系结构。
在隐式转换期间,unsigned char
可能变成 int
或 unsigned int
。
这是否意味着以下代码具有未指定的行为?
#include <iostream>
void function(unsigned int){
std::cout << "unsigned\n";
}
void function(int){
std::cout << "signed\n";
}
int main() {
char c;
function(c);
}
我没有收到任何编译器警告。它会始终解析为 "signed" 吗?
这只是一种 C++ 特性,称为 "Implicit type conversion/automatic type conversion/coercion"。当您将 char 传递给函数时,char 会隐式转换为 signed int。就像代码 "int a = 'C';" 你可以从这里了解更多关于强制转换的信息:http://www.learncpp.com/cpp-tutorial/44-implicit-type-conversion-coercion/
在幕后,所有类型都表示为二进制数,因此类型只是编译解释的一种方式。上面没有你说的这种机制
您的图表对于 整数提升 的情况是正确的。但是,在代码 function(c)
中,不会发生整数提升。这实际上是过载分辨率。如果只有一个 function
,则 c
被 转换 (未提升)为参数类型,以参数类型为准。
在重载决议的规则中,如果参数可以通过整数提升来匹配参数,那么该函数将被认为比另一个函数更匹配整数转换 需要匹配。
请参阅 C++14 中的 Table 12(第 13.3.3.1.2 节的一部分),其中列出了用于重载解析的隐式转换序列的等级。
因此您的代码示例将在具有 CHAR_MAX > INT_MAX
的系统上调用 function(unsigned int)
。
但是类型的大小是实现定义的,而不是未指定。
A char
几乎总是会转换为 int
。每当 sizeof(int) > sizeof(char)
然后 char
将被提升为 int
无论它是有符号的还是无符号的,就像你说的 int
可以容纳 [=10= 的整个范围].
你唯一能得到 unsigned int
的时间是 sizeof(char) == sizeof(int)
。在这种情况下,如果 char
是无符号的,那么它将被转换为 unsigned int
,因为 int
将无法保存整个值范围。
这可能会发生,因为标准仅规定 int
必须至少具有与 char
一样多的存储空间,因此可能存在一些具有 32 位字节的系统并且它们使 char
和 int
大小相同。
所以这是实现定义的行为,因为您需要知道实现定义的两种类型的大小和实现定义的 char
签名才能知道会发生什么。