如果我有这样的内容:
int a = 20;
int min = INT_MIN;
if(-a - min)
//do something
假设INT_MIN为正数时大于INT_MAX。编译器是否会将min转换为像-INT_MIN这样的东西,这可能是未定义的?
如果我有这样的内容:
int a = 20;
int min = INT_MIN;
if(-a - min)
//do something
INT_MIN
进行一元减运算可能是未定义的,但在您的示例中并没有发生这种情况。
-a - min
被解析为 (-a) - min
。变量 min
仅涉及二元减法,第一个操作数只需要严格为负即可定义结果。min + a
是一样的吗? - user2672807-(min + a)
是相同的。我似乎找不到一个值,使得一个会导致溢出但另一个不会,但我不能确定(至少现在还不能)。 - Pascal Cuoqx
是一个 int
,并且假设使用二进制补码:当且仅当 x
是 INT_MIN
时,-x
溢出。当且仅当 x
严格为负数时,INT_MIN + x
溢出。因此,当且仅当 x
严格为负数或零时,-(INT_MIN + x)
溢出。同时,当且仅当 -x
溢出或不是严格负数时,- x - min
溢出。也就是说,当且仅当 x
是零或负数时,溢出条件相同。所以你是正确的,溢出条件是相同的。 - Steve Jessopx - y
的结果被定义为从x
中减去y
的数学结果。如果数学结果可以表示为结果类型(在这种情况下为int
),则没有溢出。
编译器可以任意转换表达式,例如通过更改
x - y
到
x + (-y)
只有在原有的行为定义良好的情况下,转换保持不变时才会进行。在y == INT_MIN
的情况下,只要计算-INT_MIN
的未定义行为产生相同的结果,就可以执行转换(通常是这样的)。
回答标题中的问题:
从任何整数中减去INT_MIN是否被认为是未定义行为?
INT_MIN - INT_MIN == 0
,不会溢出。
顺便提一下,我认为你的意思是int
而不是“integer”。int
只是几种整数类型中的一种。
std::min
(当有using
语句时),因此我建议不要使用它。 - Brian Cainusing namespace std;
是错误的,最好的保护措施是不要使用它。在不使用min
作为名称和不使用using namespace std;
的选择中,后者显然更好。特别是当问题不是min
与std::min
冲突,而是 如果 您将min
用作变量名,并且在没有限定符的情况下调用std::min
,则会出现错误。这个错误很容易修复;如果您无法自己删除using namespace std;
,那么在调用min
的地方添加限定符。 - Pete Beckermin
,因为using namespace std
(甚至是using std :: min
)非常流行,我想你可能并不介意这种情况。我们中的许多人与其他人合作编写程序代码,这些人可能没有那么注意细节,为了避免产生不必要的困惑,让我们完全避免这个问题。 - Brian Cain