我正进入(状态
Msg(3:4130) 对签名数据的按位运算将给出实现定义的结果
QAC 中的这个警告。像这样的代码
functionName( a | b | c);
QAC 上 PIC 微控制器代码。任何人都可以解释。这个警告是什么以及如何避免这个警告。
不要将有符号整数用于按位运算,请使用unsigned
.
这就是警告告诉你的。
您没有显示 , 和 的类型a
,b
因此c
很难更具体。
负数在系统中有多种表示方式。
有符号幅度:第一位为0,则数字为正,如果第一位为1,则数字为负。
2 的补码
1 的补码
所以C从不强制数字在不同系统中的表示方式,所以这条线与数字在系统中的表示方式一致。
在进行按位运算之前,您应该注意小端和大端表示。
对有符号数据(INT,LONG)的按位(|,&)操作将为您提供与实现相关的结果。您可以通过在执行按位运算之前使用转换为无符号的类型来避免它。
在您的代码中functionName( a | b | c);
您functionName
使用a | b | c
where 作为参数调用此函数, where|
执行按位运算。对有符号整数 (a,b,c)执行按位运算 ( |
) 将返回实现定义的结果。
您可以通过类型转换变量 a,b,c 来避免此警告,如下所示
functionName( (unsigned)a | (unsigned)b | (unsigned)c)
上面的代码会改变 a,b,c 的类型,这样就可以避免 QAC 警告
负数有不同的表示方案,
例如这三种(使用 8 位示例)。
平等不一样
补充2:
(-1 | -2)
== ((0xff ^ 1)+1) | ((0xff ^ 2)+1)
== (0xfe+1) | (0xfd+1)
== (0xff) | (0xfe)
== 0xff
== (0xfe +1)
== ((0xff ^ 1) +1)
== -1
== -( ((1+1) & (2+1)) -1 )
补充 1:
(-1 | -2)
== (0xff ^ 1) | (0xff ^ 2)
== (0xfe) | (0xfd)
== (0xff)
== (0xff ^ 0x00)
== -0
== - ( 1 & 2 )
有符号幅度:
(-1 | -2)
== (0x80 | 1) | ( 0x80 | 2 )
== (0x81) | (0x82)
== (0x83) == (0x80 | 3)
== -3
== -( 1 | 2 )
这就是“实现定义”的含义,具体取决于您的编译器:
(-1 | -2) == -3 == -( 1 | 2 )
(-1 | -2) == -0 == -( 1 & 2 )
(-1 | -2) == -1 == -( ((1+1) & (2+1)) -1 )
“将这些变量的值视为负数,
仅仅因为最高位是 1,
是愚蠢的,它们只是位!” 你说?
或者,“价值永远不会这么高,而且在语义上也绝对不会是负面的。”
好吧,那就不要为他们使用signed int。
这就是 QAC 想要告诉你的。
如果您碰巧不知道它,
我敢打赌您永远猜不到您的编译器
(或至少当今大多数实际硬件实现的 ALU 的编译器)使用哪种表示形式。