【问题标题】:Assigning an out-of-range integer to a signed char type将超出范围的整数分配给带符号的 char 类型
【发布时间】:2020-02-11 23:56:42
【问题描述】:

signed char a = 128;
假设一个字节是8位,这是未定义的吗?
我所知道的是,将超出范围的值分配给有符号类型是未定义的,但 Bjarne Stroustrup 在 C++ 编程语言中说,如果我将整数 255 分配给 8 位字节机器上的 char,其中 char 已签名结果是-1。

【问题讨论】:

  • 来源:C++ 编程语言 - 第 4 版 - 6.2.3.1 有符号和无符号字符 - 第 142 页
  • 它是实现定义的(编译器必须记录行为)

标签: c++ type-conversion


【解决方案1】:

这是未定义的吗?

没有。

我知道将超出范围的值分配给有符号类型是未定义的

也没有。

控制这一点的规则是整数类型之间的转换。转换是用于初始化还是赋值无关紧要。

将整数值转换为有符号整数类型时, 如果结果不可表示,则:

current 标准 C++17 中:结果值将由实现定义。

upcoming 标准 C++20 中:该值将与原始值模 2N 一致,其中 N 是目标类型的宽度(仅就像无符号整数一样)。 -1 等于 255 模 28


请注意,与转换不同,有符号算术溢出的行为是未定义的。

【讨论】:

  • 感谢您的回答,但我还有一个问题,C++ Primer 指出“如果我们将超出范围的值分配给带符号类型的对象,则结果未定义”。是错了还是有什么我不明白的地方?
  • @Mason 这看起来像是个错误。这至少有点误导。
  • +1 在阅读 C++ Primer 中的那一行后出现,鉴于上述讨论,这似乎是不准确的。另外,请考虑一下,如果intsigned char 可能 具有未定义的行为,那么static_cast<char>(std::toupper(static_cast<unsigned char>(ch))); 将毫无意义,其中toupper 返回int。见en.cppreference.com/w/cpp/string/byte/toupper
  • 这是否意味着对于signed charshort int 类型(假设char 不可能? (我的意思是,有符号整数溢出仍然可能发生,但不会超出signed charshort int 的范围。)原因是通常的算术转换会将两个操作数提升到至少int在对结果应用实现定义的隐式转换之前。
  • @303 确实如此。由于没有低于int 等级的算术运算,因此只有超过int 的限制(或更高等级的整数更大)才能溢出。
猜你喜欢
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2014-04-29
  • 2019-12-23
相关资源
最近更新 更多