繁体   English   中英

编译器警告:负值左移

[英]compiler warning: left shift of negative value

我认为 GCC 错误地产生了 [-Wshift-negative-value] 警告。

我有一个 function 应该产生一个由其单个输入参数提供的特定长度的后缀掩码:

#include <stdint.h>

uint16_t get_suffix_mask_sht(uint8_t shift) {
    return (~(~((uint16_t) 0) << shift));
}

我尝试在不同版本的 gcc 上使用以下编译器选项编译此 function

-Werror -Wextra

如果我将 output 从uint16_t更改为uint8_t ,也会出现此警告。 更大的 output 类型,即uint32_t不会产生此警告。

我使用的是旧版本的 GCC:7.4。 但是我已经使用最新的 GCC 9.x 版本在Godbolt上进行了尝试,它们都产生了相同的警告。 Clang 版本但是不会产生此错误。

当小于int的变量(例如uint16_t )与按位补码运算~一起使用时,它们被提升为int

int类型是有符号的,并且不适用于移位。 特别是考虑到~0将是带有二进制补码符号的-1 (这是在二进制系统上表示负数的最常见符号)。

一种可能的解决方案是使用较大的无符号类型(如unsigned int ),然后在完成后使用屏蔽来获取较小类型的相关位。

警告是正确的。

~((uint16_t) 0)产生负值,因为(uint16_t) 0 uint16_t) 0 的结果在执行按位补码之前被提升为int

通常,在使用位移时,您应该更喜欢无符号整数(足够宽以避免类型提升)。 我的建议是使用unsigned int zero 代替:

return (~(~0U << shift));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM