gpt4 book ai didi

c++ - 带整数提升的位运算

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:51 26 4
gpt4 key购买 nike

tl;dr 当经过整数提升(类型短于 int)时,位操作是否安全且行为符合预期?

例如

uint8_t a, b, c;
a = b & ~c;

这是我所拥有的粗略 MCVE:

struct X { // this is actually templated
using U = unsigned; // U is actually a dependent name and can change
U value;
};

template <bool B> auto foo(X x1, X x2) -> X
{
if (B)
return {x1.value | x2.value};
else
return {x1.value & ~x2.value};
}

这很好用,但是当 U 更改为比 int 短的整数类型时,例如std::uint8_t 然后由于整数提升我收到警告:

warning: narrowing conversion of '(int)(((unsigned char)((int)x1.X::value)) | ((unsigned char)((int)x2.X::value)))' from 'int' to 'X::U {aka unsigned char}' inside { } [-Wnarrowing]

所以我添加了一个static_cast:

struct X {
using U = std::uint8_t;
U value;
};

template <bool B> auto foo(X x1, X x2) -> X
{
if (B)
return {static_cast<X::U>(x1.value | x2.value)};
else
return {static_cast<X::U>(x1.value & ~x2.value)};
}

问题:整数提升和缩小转换是否会混淆预期结果 (*)?特别是因为这些强制转换会前后更改符号(unsigned char -> int -> unsigned char)。如果 U 已签名,即 std::int8_t 怎么办(它不会在我的代码中签名,但对它的行为感到好奇)。

我的常识认为代码完全没问题,但我的 C++ 偏执狂认为至少有机会实现定义的行为。

(*) 如果不清楚(或者我搞砸了),预期行为是设置或清除位(x1 是值,x2 是掩码,B 是设置/清除操作)

最佳答案

如果你使用无符号类型,一切都会好的。标准要求对于无符号目标整数类型,窄化是完美定义的:

4.7 Integral conversions [conv.integral]
...
2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type).

但如果目标类型已签名,则结果是实现定义,根据下一段(强调我的):

3 If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.

在常见的实现中,一切都会好起来的,因为对于编译器来说,通过只为无符号或有符号类型保留低级字节来简单地进行缩小转换会更简单。但该标准只要求实现定义将发生什么。一个实现可以记录当原始值不能在目标类型中表示时将值缩小为有符号类型给出 0,并且仍然是一致的。


顺便说一句,由于 C++ 和 C 通常以相同的方式处理转换,应该注意 C 标准略有不同,因为最后一种情况可能会引发信号:

6.3.1.3 [Conversions] Signed and unsigned integers
...
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.

还是确认C和C++是不同的语言...

关于c++ - 带整数提升的位运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40721742/

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