gpt4 book ai didi

c - += uint16_t 的运算符将分配的值提升为 int 并且不会编译

转载 作者:太空狗 更新时间:2023-10-29 16:19:28 26 4
gpt4 key购买 nike

这对我来说是一个真正的 WTF,看起来像是 GCC 中的一个错误,但我想让社区看看并找到适合我的解决方案。

这是我能收集到的最简单的程序:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
uint16_t i = 1;
uint16_t j = 2;
i += j;
return i;
}

我正在尝试使用 -Werror=conversion 标志在 GCC 上编译它,我的大部分代码都在使用它。

结果如下:

.code.tio.c: In function ‘main’:
.code.tio.c:9:7: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i += j;

这段代码会发生同样的错误:

uint16_t i = 1;
i += ((uint16_t)3);

错误是

.code.tio.c: In function ‘main’:
.code.tio.c:7:7: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i += ((uint16_t)3);
^

需要说明的是,这里的错误是在 += 运算符上,而不是在强制转换上。

看起来 +=uint16_t 的运算符重载搞砸了。还是我在这里遗漏了一些微妙的东西?

供您使用:MCVE

编辑:一些相同的:

.code.tio.c:8:6: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i = i + ((uint16_t)3);

但是 i = (uint16_t)(i +3); 至少可以工作...

最佳答案

隐式转换的原因是由于 += 的等价性运算符 =+ .

来自 C standard 的第 6.5.16.2 节:

3 A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation

所以这样:

i += ((uint16_t)3);

相当于:

i = i + ((uint16_t)3);

在此表达式中,+ 的操作数运算符被提升为 int ,那int被分配回 uint16_t .

第 6.3.1.1 节详细说明了这样做的原因:

2 The following may be used in an expression wherever an int or unsigned int may be used:

  • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
  • A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

因为 uint16_t (又名 unsigned short int )的排名低于 int ,当用作 + 的操作数时,这些值会被提升.

您可以通过分解 += 来解决这个问题运算符(operator)和类型转换右侧。此外,由于提升,对值 3 的强制转换没有任何效果,因此可以将其删除:

i =  (uint16_t)(i + 3);

但是请注意,此操作可能会溢出,这是在没有转换时发出警告的原因之一。例如,如果 i值为 65535,则为 i + 3类型为 int和值 65538。当结果返回到 uint16_t 时,从该值中减去值 65536 得到值 2,然后将其分配回 i .

这种行为在这种情况下得到了很好的定义,因为目标类型是无符号的。如果目标类型已签名,则结果将由实现定义。

关于c - += uint16_t 的运算符将分配的值提升为 int 并且不会编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47417034/

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