gpt4 book ai didi

c - C 中的有符号到无符号转换 - 它总是安全的吗?

转载 作者:行者123 更新时间:2023-11-30 16:57:55 24 4
gpt4 key购买 nike

假设我有以下 C 代码。

unsigned int u = 1234;
int i = -5678;

unsigned int result = u + i;

这里发生了什么隐式转换,这段代码对于 ui 的所有值都是安全的吗? (安全,因为即使本例中的结果会溢出到某个巨大的正数,我也可以将其转换回 int 并获得真正的结果。)

最佳答案

简答

通过添加 UINT_MAX + 1,您的 i转换为无符号整数,然后使用无符号值进行加法,导致较大的结果(取决于ui的值)。

长答案

根据C99标准:

6.3.1.8 Usual arithmetic conversions

  1. If both operands have the same type, then no further conversion is needed.
  2. Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
  3. Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
  4. Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
  5. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

就您而言,我们有一个无符号整型 (u) 和有符号整型 (i)。引用上面的 (3),由于两个操作数具有相同的秩,因此您的 i 将需要转换为无符号整数。

6.3.1.3 Signed and unsigned integers

  1. When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
  2. Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
  3. Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

现在我们需要引用上面的(2)。您的 i 将通过添加 UINT_MAX + 1 转换为无符号值。因此,结果将取决于 UINT_MAX 在您的实现中的定义方式。它会很大,但不会溢出,因为:

6.2.5 (9)

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

奖励:算术转换半WTF

#include <stdio.h>

int main(void)
{
unsigned int plus_one = 1;
int minus_one = -1;

if(plus_one < minus_one)
printf("1 < -1");
else
printf("boring");

return 0;
}

您可以使用此链接在线尝试:https://repl.it/repls/QuickWhimsicalBytes

奖励:算术转换副作用

可以使用算术转换规则,通过将无符号值初始化为-1来获取UINT_MAX的值,即:

unsigned int umax = -1; // umax set to UINT_MAX

由于上述转换规则,无论系统的有符号数字表示如何,都保证是可移植的。请参阅此问题以获取更多信息:Is it safe to use -1 to set all bits to true?

关于c - C 中的有符号到无符号转换 - 它总是安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39242475/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com