GCC 改变符号整个表达式

GCC changing signdess whole expression

我有以下代码:

unsigned int m_font_timer = 0;

int Getsum(int p_top_left_x)
{
    int l_sum = (((p_top_left_x + (m_font_timer >> 2)) & 0x7) - 4 ) >> 2;
    
    if (l_sum < 0) l_sum = -l_sum;
    return l_sum;
}

除非我明确地将 m_font_timer 转换为 (signed int) 表达式的这一部分变为无符号的:

((p_top_left_x + (m_font_timer >> 2)) & 0x7) - 4 );

即使有一个“-4”并且 p_top_left_x 已签名。

这是在使用 gcc 4.7.3 的 SH4 交叉编译器上发生的(我正在为需要它的旧系统编程)。 我没想到那部分会变成未签名的。我在其他两个平台上也有这个代码 运行 也有 GCC(比这个版本更高)和一个有 MSCV,它们都保持上述表达式的签名。

我不太了解编译器,这是未定义的行为吗? 编译器有什么办法可以警告我吗?我有 -Wall -Wformat=0 -Wextra -Wsign-compare 但在该函数中没有出现任何警告。

谢谢!

类型转换按等级和符号进行: 如果类型的级别不同 - 如 int 和 char,较低级别 (char) 将转换为较高级别 (int)。

如果两种类型的级别相同但符号不同 - 除非另有明确说明,否则有符号类型将转换为无符号类型。

这里有几个地方解释的很详细:

usual arithmatic conversion

another source