gpt4 book ai didi

c - 分配给位域时的 GCC 转换警告

转载 作者:太空狗 更新时间:2023-10-29 17:02:57 25 4
gpt4 key购买 nike

有什么办法可以抑制 gcc 在此代码中生成的警告:

int main() {
struct flagstruct {
unsigned flag : 1;
} a,b,c;

a.flag = b.flag | c.flag;

return a.flag;
}

警告是

warning: conversion to 'unsigned char:1' from 'int' may alter its value [-Wconversion]

看起来这两个标志在 ored 在一起时扩展为 int。我认为真正奇怪的是,将两个标志中的任何一个强制转换为 unsigned 都会抑制警告。

a.flag = (unsigned)b.flag | c.flag;

这是编译器错误还是应该以这种方式工作?

最佳答案

It looks like the the two flags are extended to int when ored together.

这是整数提升,它在 C99 标准的措辞奇怪的条款 6.3.1.1:2 中定义:

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

— A bit-field of type _Bool, int, signed int, or unsigned int. If an int can represent all values of the original type, 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.

首先,处理器不直接对位域进行计算,也可能没有指令对较窄的整数类型 charshort 进行计算。 C 标准通过仅在 intunsigned int 和更宽的整数类型上定义算术运算来捕捉这一点。在标准上面说“可以使用”的地方,它试图(不好地)表达必须将所有短类型和位字段提升为int unsigned int 在参与算术之前。

其次,所有宽度不足以包含不能表示为 int 的值的无符号位域都被提升为 int。换句话说,GCC 通过将您的无符号位域提升为带符号的 int 来按照标准行事,并像您一样添加显式强制转换,这似乎是防止 future 出现意外情况的最佳策略(并反对警告)。

What I think is really strange is that casting any of the two flags to unsigned supresses the warning.

常规算术转换,C 标准(C99 中的 6.3.1.8)中的另一个有趣概念,其结果是,如果两个操作数中的任何一个被显式转换为 unsigned int,那么这次另一个操作数也被隐式转换为 unsigned int 并且 | 操作是一个 unsigned int 操作产生unsigned int 结果。

换句话说,(unsigned)b.flag | c.flag 严格等同于 (unsigned)b.flag | (无符号)c.flag。在这种情况下,编译器认为没有理由对赋值发出警告,因为计算结果是 unsigned int

关于c - 分配给位域时的 GCC 转换警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25480059/

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