问题标签 [integer-promotion]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - unsigned char 是否总是提升为 int?
假设如下:
是否保证foo
和bar
值被提升为int
用于评估表达式的值foo + bar
- 或者是否允许实现将它们提升为unsigned int
?
在第 6.2.5 节第 8 段中:
对于任何两个具有相同符号和不同整数转换等级的整数类型(见 6.3.1.1),具有较小整数转换等级的类型的值范围是另一个类型的值的子范围。
在第 6.2.5 节第 9 段中:
如果 an
int
可以表示原始类型的所有值,则将该值转换为int
; 否则,将其转换为unsigned int
.
具有较小整数转换等级的整数类型的值范围是其他类型值的子范围的保证似乎取决于整数类型的符号性。
signed char
对应于signed int
unsigned char
对应于unsigned int
这是否意味着 an 的值unsigned char
只保证在 的子范围内unsigned int
,而不一定在 的子范围内int
?如果是这样,这是否意味着一个实现理论上可能具有一个unsigned char
不在 a 子范围内的值int
?
c - 独立于编译器的表达式算术转换和整数提升
假设我们有一个使用以下类型变量的赋值:
uint64 = uint16 + uint16 + uint32 + uint64
假设我们知道只要所有工作都使用 uint64 完成,生成的 r 值就适合 uint64。
在按照标准 C 规则进行任何计算之前,编译器是否会隐式地将两个 uint16 和 uint32 提升为 uint64?
IE
1.)uint64 = uint16 + uint16 + uint32 + uint64
2.)uint64 = uint64 + uint64 + uint64 + uint64
特别是通过应用以下代码段中的第二条语句:
如果两个操作数具有相同的类型,则不需要进一步转换。
否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则具有较小整数转换等级的类型的操作数将转换为具有较高等级的操作数的类型。
否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。
否则,两个操作数都转换为与带符号整数类型的操作数类型对应的无符号整数类型。
或者该规则是否仅适用于算术表达式的直接 lhs 和 rhs,以便可能首先计算添加两个 uint16,其中在知道结果之前不会提升类型,然后将其提升为 uint32,然后是这个结果提升为uint64等...
IE
1.)uint64 = uint16 + uint16 + uint32 + uint64
2.)uint64 = (((uint16 + uint16) + uint32) + uint64)
3.)uint64 = ((uint32 + uint32) + uint64)
4.)uint64 = (uint64 + uint64)
请向我指出任何可能为我解决这个问题的 C 标准规则。
c - unsigned char 的按位否定
这是一个与 c99 标准相关的问题,涉及 unsigned char 的整数提升和按位否定。
在第 6.5.3.3 节中,它指出:
整数提升在操作数上执行,结果具有提升的类型。如果提升的类型是无符号类型,则表达式 ~E 等价于该类型中可表示的最大值减去 E。
当我这么说时,我是否理解正确,这意味着:
我的困惑源于与一位同事的讨论,他在我们的编译器中看到了以下行为。
使用 gcc 确认了此行为。
是否有可能获得正确的预期字符比较,其中每个案例都将评估为真?
c - 打印字符时会发生哪些整体促销活动?
我最近读到
调用未定义的行为,因为由于格式说明符 %u,printf 需要一个无符号整数。但我仍然想了解这个例子中发生了什么。
我认为积分提升规则适用于由 .printf("%u",x)
表示的表达式和值x
。
A.6.1 积分促销
一个字符、一个短整数或一个整数位域,无论是否有符号,或枚举类型的对象,都可以在可以使用整数的表达式中使用。如果一个 int 可以表示原始类型的所有值,则将该值转换为 int;否则,该值将转换为 unsigned int。这个过程称为积分提升。
这里的“可以使用”是什么意思?这是否意味着“语法正确”或“已定义行为”?
在这个例子中 x 是如何提升的?我读过它被提升为int,但如果printf("%u", (int x))
仍然是未定义的行为,那么我真的不明白为什么......
c - 为什么 (int64_t)-1 + (uint32_t)0 签名?
为什么(int64_t)-1 + (uint32_t)0
用C签名?看起来是这样int64_t
,但我的直觉会说uint64_t
。
仅供参考当我跑步时
我得到以下输出:
c++ - 为什么 C/C++ 会自动将 char/wchar_t/short/bool/enum 类型转换为 int?
所以,如果我理解得很好,积分提升规定:char, wchar_t, bool, enum, short
类型总是被转换为int
(或unsigned int
)。然后,如果表达式中有不同的类型,将应用进一步的转换。
我理解这个很好吗?
如果是,那么我的问题是:为什么它很好?为什么?不要变得char/wchar_t/bool/enum/short
不必要?我的意思是例如:
正如我之前所描述的,char
ALWAYS 被转换为int
,所以在这种情况下,在自动转换之后,它看起来像这样:
但我不明白为什么这么好,如果我知道那种char
类型足以满足我的需要。
c - 添加两个 uint8_t 时的转换警告
我有以下 C 代码:
当我使用 编译此代码时gcc -Wconversion
,我收到以下警告:
有人可以解释为什么会出现这个警告吗?所有三个变量都是 type uint8_t
,所以我不太明白它的int
来源。
c - 关于整数提升的问题,C 中的转换
这个话题在很多情况下都被大量讨论过。当我搜索并阅读一些帖子时。我被以下帖子弄糊涂了。
以下是原始问题。
答案只是引用了“6.3.1.8 通常的算术转换”第 3 点,即
否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
但是,如果我的理解是正确的,那么应该在考虑“通常的算术转换”之前进行整数提升。
规则是
如果 int 可以表示原始类型的所有值,则该值将转换为 int 。否则,它将转换为 unsigned int 。这些转换规则称为积分促销
因此,这意味着添加是使用有符号 int 类型而不是unsigned int类型完成的。当将负数分配给unsigned int结果时,会发生转换为大值。
我对自己的理解有点不自信。有没有人对那个帖子有类似的困惑?
欢迎任何回复或评论。提前谢谢!
杰夫
c - `uint_fast32_t` 是否保证至少与 `int` 一样宽?
C 标准规定,在对其执行任何算术运算之前,小于int
将被提升的整数操作数。int
因此,对两个小于 的无符号值的操作int
将使用有符号而不是无符号数学来执行。在确保使用无符号数学对 32 位操作数进行操作很重要的情况下(例如,将乘积可能超过 2⁶³ 的两个数字相乘)将由uint_fast32_t
任何标准保证使用该类型以产生无符号语义而没有任何未定义行为? 如果没有,是否有任何其他无符号类型保证至少为 32 位且至少与 一样大int
?
c - 为什么组合 uint8_t 的两个班次会产生不同的结果?
有人可以解释一下为什么:
和:
在 C 中产生不同的答案?x
是 *uint8_t* 类型(无符号 1 字节长整数)。例如,当我128 (10000000)
在第一种情况下传递它时,它会返回0
(正如预期的那样,最高有效位会掉出来),但在第二种情况下,它会返回原始的128
. 这是为什么?我希望这些表达式是等价的?