【问题标题】:Is resolving char between signed and unsigned int unspecified?解析有符号和无符号整数之间的字符是否未指定?
【发布时间】:2016-10-27 02:52:16
【问题描述】:

据我了解,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);
}

我没有收到任何编译器警告。它总是会解析为“签名”吗?

【问题讨论】:

标签: c++ function char implicit-conversion overload-resolution


【解决方案1】:

char 几乎总是会转换为 int。每当sizeof(int) &gt; sizeof(char) 然后char 将被提升为int,无论它是签名还是未签名,就像你说的int 可以容纳char 的整个范围。

您唯一可以获得unsigned int 的时间是sizeof(char) == sizeof(int)。在这种情况下,如果char 是无符号的,那么它将被转换为unsigned int,因为int 将无法保存整个值范围。

这可能会发生,因为标准仅规定 int 必须至少具有与 char 一样多的存储空间,因此可能存在一些具有 32 位字节的系统,它们使 charint 成为大小相同。

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

【讨论】:

    【解决方案2】:

    对于整数提升,您的图表是正确的。但是,在代码function(c) 中,不会发生整数提升。这实际上是重载分辨率。如果只有一个function,那么c转换(不提升)为参数的类型,无论它是什么。

    在重载决议的规则中,如果参数可以通过整数提升来匹配参数,那么该函数将被认为比另一个需要 整数转换 匹配的函数更好.

    请参阅 C++14 中的表 12(第 13.3.3.1.2 节的一部分),其中列出了用于重载解析的隐式转换序列的等级。

    因此,您的代码示例将在具有CHAR_MAX &gt; INT_MAX 的系统上调用function(unsigned int)

    但是类型的大小是实现定义的,而不是未指定的

    【讨论】:

      【解决方案3】:

      这只是一种 C++ 特性,称为“隐式类型转换/自动类型转换/强制”。当您将 char 传递给函数时,char 被隐式​​转换为 signed int。就像代码“int a = 'C';”你可以从这里了解更多关于强制的信息:http://www.learncpp.com/cpp-tutorial/44-implicit-type-conversion-coercion/

      在底层,所有类型都表示为二进制数,所以类型只是编译的一种解释方式。上面没有你说的这种机制

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-31
        • 2012-04-07
        • 2013-10-02
        • 2015-02-17
        • 2014-10-15
        • 2016-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多