是否在未指定的 signed 和 unsigned int 之间解析 char?

Is resolving char between signed and unsigned int unspecified?

据我了解,char 可能有不同的基础类型,具体取决于体系结构。
在隐式转换期间,unsigned char 可能变成 intunsigned 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 位字节的系统并且它们使 charint 大小相同。

所以这是实现定义的行为,因为您需要知道实现定义的两种类型的大小和实现定义的 char 签名才能知道会发生什么。