|
1
142
不幸的是,隐式类型提升的规则弊大于利,甚至可能是C语言中最大的缺陷之一。这些规则通常连一般的C程序员都不知道,因此会导致各种各样的非常微妙的错误。 通常你会看到程序员说“只要转换到x类型就行了”的场景,但他们不知道为什么。或者,这些bug表现为罕见的间歇性现象,从看似简单直接的代码中突现出来。隐式提升在执行位操作的代码中特别麻烦,因为C中的大多数位运算符在给定有符号操作数时都具有定义不好的行为。 整数类型和转换秩
C中的整数类型是
所有整数都有一个指定的 转换秩
此外,C11 6.3.1.1规定了哪些类型被视为 小整数类型 (非正式术语):
这个有点晦涩的文本在实践中的意思是
每当在表达式中使用小整数类型时,它都会隐式转换为
从形式上讲,该规则说(C11 6.3.1.1):
本文经常被误解为:“所有小的有符号整数类型都转换为有符号整数,所有小的无符号整数类型都转换为无符号整数”。这是不正确的。这里的无符号部分仅意味着,如果我们有一个
这听起来可能是胡说八道,但幸运的是编译器可以优化代码。例如,一个表达式包含两个
通常的艺术转换 (有时非正式地称为“平衡”)。这些在C11 6.3.18中规定:
|
|
2
8
由于无符号字符小于int,我们对其应用整数提升,因此我们得到(int)x-(int)y=(int)(-1)和无符号int(-1)=4294967295。 上述代码的输出:(与我们预期的相同)
我尝试了上一篇文章推荐的方法,但实际上并不奏效。 以下是基于之前帖子的代码:
由于x已经是一个无符号整数,我们只对y应用整数提升。然后我们得到(无符号int)x-(int)y。由于它们仍然没有相同的类型,我们应用通常的算术凸,我们得到(无符号int)x-(无符号int)y=4294967295。 上述代码的输出:(与我们预期的相同):
类似地,以下代码得到相同的结果:
将两者都更改为无符号int
修复代码的可能方法之一:(在末尾添加类型转换)
由于两者都是整数,因此不需要整数提升。通过通常的算术转换,我们得到(无符号int)a+(无符号int)b=1+4294967294=4294967295。
如何修复?
示例3)
最后一个示例修复了这个问题,因为a和b都由于整数提升而转换为int。 上述代码的输出:
如果我混淆了一些概念,请告诉我。谢谢~ |
|
3
0
C和C中的整数和浮点秩及提升规则++the main one by @Lundin . 如果你想在下面的例子之外找到更多的例子,那么也可以详细研究这个答案,同时参考我下面的“规则”和“促销流程”总结。 我还在这里编写了自己的示例和演示代码: integer_promotion_overflow_underflow_undefined_behavior.c .
3条简单规则
实例示例:使用此代码:
...如果你这样做了
促销规则如下。晋升自
类型如下。
注:
=
小型:
2.对于浮点类型
|
|
|
MaPo · Linux,设置锁定ICMP_过滤器选项 1 年前 |
|
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 1 年前 |
|
|
Bobby · 复合字面值总是左值吗? 1 年前 |
|
9-Pin · C: 嵌套结构的堆栈内存分配 1 年前 |