AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 76969417
Accepted
LiDa Cute
LiDa Cute
Asked: 2023-08-24 20:46:59 +0800 CST2023-08-24 20:46:59 +0800 CST 2023-08-24 20:46:59 +0800 CST

为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

  • 772

我读过这个

整数提升:小整数类型(例如 char)的纯右值可以转换为较大整数类型(例如 int)的纯右值。- 第一行
[...详细信息 - 不重要...]
请注意,所有其他转化都不是促销;例如,重载决策选择 char -> int (提升)而不是 char -> Short (转换)。- 最后一行。

从 char -> int 的转换是 'promotion' ;很明显(从 1 个字节到 4 个字节)
从 char -> Short 的转换是“不升级”;为什么?
我一直认为char是一个字节,short(short int)是两个字节。为什么它不被视为促销?这似乎与第一行相矛盾 - 这不是意味着“从小类型转换为大类型”是升级吗?)
-----编辑:在寻找一些答案后:
我们可以考虑“促销是转换的特殊情况”吗?,我们是否可以说“所有促销都是转化,但并非所有转化都是促销”?
或者我们应该将它们视为两个不同且独立的概念?

c++
  • 4 4 个回答
  • 472 Views

4 个回答

  • Voted
  1. Best Answer
    Jan Schultke
    2023-08-24T21:02:53+08:002023-08-24T21:02:53+08:00

    历史动机:C

    积分提升的思想可以追溯到标准之前的 C。当向可变参数函数 ( ...) 或没有原型的函数提供参数时,就会应用提升。即调用:

    // function declaration with no prototype
    void mystery();
    // ...
    char c = 'c';
    mystery(c); // this promotes c to int
    
    // in another .c file, someone could define
    void mystery(int x) { /* ... */ }
    

    促销基本上是对该类型的“最小”升级,而转换可以是任何内容。您甚至可以认为该设计是基于 B 编程语言构建的结果,该语言甚至没有像 C 那样具有多种整数类型。

    C++标准中的相关措辞

    标准C++中的相关段落是:

    如果纯右值不是转换后的位域,并且其整数类型不是bool、char8_t、char16_t、char32_t,或者wchar_t其整数转换等级小于 的等级,则int可以转换为该类型的纯右值int(如果int可以表示源类型的所有值) ; 否则,可以将源纯右值转换为 类型的纯右值unsigned int。

    - [转换舞会] p2

    促销和转化之间的区别解释如下:

    积分促销允许的转化不包括在积分转化集中。

    - [转换积分] p4

    正如您所看到的,这两个概念之间存在一些重叠,但任何同时也是促销的转换都不被视为转换。

    对过载解决的影响

    正如您所指出的,char -> short是转换,char -> int是晋升。在某些情况下,这会对重载解析产生重大影响:

    // A conversion sequence from char -> int is empty
    // because char -> int is a promotion, and so it doesn't contribute
    // to the conversion sequence.
    void f(int);
    // A conversion sequence from char -> short has length 1
    // because char -> short is not a promotion.
    void f(short);
    
    int main() {
        // Not an ambiguous call; calls f(int), because the conversion sequence
        // for this call is shorter.
        // Note that in C, a character literal has type 'int', not 'char', so
        // it is more symmetrical to favor 'int' whenever possible.
        f('x');
    }
    

    如果现在 C++ 是从头开始设计的,那么升级和转换的定义可能会有很大不同,但是,现状就是我们所拥有的,而且不太可能改变。经过这么多年,改变这种行为和措辞基本上是不可能的,因为有多少代码依赖于它。

    与 C++ 中的许多设计决策一样,答案是:历史原因。

    • 11
  2. Eric Postpischil
    2023-08-24T21:16:04+08:002023-08-24T21:16:04+08:00

    tochar和toint都是转换。请注意在讨论促销后文本使用“所有其他转化”:促销是转化的一种类型。charshort

    转换是一种操作,它采用一种形式的值并以另一种形式产生相同的值(尽可能接近):

    • 获取一个char值并生成int具有相同值的值是一种转换。
    • 获取一个int值并生成一个包含表示相同值的十进制数字的字符串是一种转换。
    • 以磅为单位的重量并以公斤为单位产生相同的重量是一种转换。

    在表达式的许多地方,C++ 自动将窄整数类型转换为更宽的整数类型。这样做主要是出于历史目的,而且还因为纯粹以狭窄类型进行算术可能会很尴尬 -char算术很容易溢出,并且要求程序员显式插入强制转换int会使代码变得麻烦。

    这些特殊的转换称为“促销”。该词的自然英语含义,前进到更高的位置,适合这些类型的转换:它们都从较窄的类型转换为较宽的类型(或至少转换为更宽的类型)。除此之外,这个词被用来专门指代这些特殊的转换。积分促销的一个重要特点是其价值永远不会改变。(理想情况下,任何转换都不会改变值,但由于限制,这种情况确实会发生。一个例子是,将值float3¼ 转换为int必须生成一个整数,因此生成 3 而不是 3¼。另一个例子是,将int值转换为 -3到unsigned力环绕,因此会产生名义上非常不同的值,尽管它确实与输入值有特殊关系并且在模算术中可以被视为相同的值。)

    • 8
  3. NoName
    2023-08-24T20:55:34+08:002023-08-24T20:55:34+08:00

    C++ 标准指定了一组整数提升规则,这些规则不仅仅基于类型的大小。char将 a 升级为 anint而不是 a的决定short基于该语言的历史设计以及跨不同平台一致行为的愿望。

    根据 C++ 标准,定义整型提升以将小整型类型转换为特定的实现定义类型,通常是int. 由于int选择 为积分提升的目标类型,因此将 a 转换char为 ashort并不符合提升资格,即使short大于char。相反,它属于转换类别。

    不同的实现和架构之间的具体规则可能有所不同,但这是您观察到的行为背后的一般推理。它是语言设计的一部分,以历史考虑和编译器实现的实际方面为指导,而不是基于类型大小的严格逻辑进展。

    • 2
  4. Steven Dickinson
    2023-08-24T21:03:04+08:002023-08-24T21:03:04+08:00

    简短的回答(对不起,双关语)就是它的定义方式。

    显然,从 char(1 个字节)到 Short(2 个字节)应该是“安全”转换(因此是“升级”?)。然而,引用的部分具体说明了哪些转化被归类为“促销”,但没有简短说明。就是这样。为什么?不确定 - 文本确实说算术运算符不接受小于 int 的操作数,因此“提升”为 Short 可能没有意义,因为它只需要在稍后的时间提升为 int 。

    • 1

相关问题

  • 为什么编译器在这里错过矢量化?

  • 使用带有库的 CMake 编译错误[关闭]

  • 每次我尝试运行预制时都会抛出错误

  • 如何在 C++ 中创建类似于 std::byte 的八位字节类型?

  • C++17 中 std::byte 只能按位运算?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve