问题描述
好的,在你用OT干草叉刺我之前,我只想提出这个问题确实与c.l.c ++有关。我的问题
是,交换两个整数的众所周知的方法是否在c ++中产生未定义的
行为?方法是:
a ^ = b ^ = a ^ = b;
这是一个聪明的伎俩,但我有一种感觉如果我在C ++中使用它,可能会出现问题,尽管使用一些编译器的快速测试会产生正确的输出。那么代码是否保证在所有
编译器上都能正常工作?谢谢。
OK, before you all stab me with your OT pitchfork, I just want to
mention that this question is indeed related to c.l.c++. My question
is, does the well-known method to swap two integers produce undefined
behaviour in c++? The method is:
a ^= b ^= a ^= b;
It''s a clever trick, but I have a feeling something may go wrong if I
use it in C++, although quick tests with a few compilers produce
correct output. So is the code guaranteed to work correctly on all
compilers? Thanks.
推荐答案
如果你在一行上写它,它似乎是UB,因为你修改了
变量a两次序列点之间(即使通过一些扩展的标准来解释,它也会被定义为明确的,它将会是糟糕的形式;但是在没有明显的情况下分离序列
点,证明定义明确的行为的负担将是那个以这种方式编码的人。可能,在评论中需要整整一段才能
证明这一行。)
但是
a ^ = b;
b ^ = a ;
a ^ = b;
有明确定义的行为。
If you write it on a single line, it would appear to be UB since you modify
the variable a twice between sequence points (and even if by some extended
exegesis of the standard it would turn out to be well-defined, it would
still be poor form; but the in the absence of obvious separating sequence
points, the burden to prove well-defined behavior would be on whoever codes
that way. Presumably, it would take a whole paragraph in comments to
justify that line).
However
a ^= b;
b ^= a;
a ^= b;
has well-defined behavior.
不,它不是。它只是代码混淆的一种形式。如果你想交换一个
,就这样说:
swap(a,b);
No, it isn''t. It''s just a form of code obfuscation. If you want to swap a
and be, just say so:
swap( a, b );
见上文。
Best
Kai-Uwe Bux
See above.
Best
Kai-Uwe Bux
如果你在一行上写它,它似乎是UB,因为你修改了
变量a两次序列点之间(即使通过一些扩展的标准来解释,它也会被定义为明确的,它将会是糟糕的形式;但是在没有明显的情况下分离序列
点,证明定义明确的行为的负担将是那个以这种方式编码的人。可能,在评论中需要整整一段才能
证明这一行。)
但是
a ^ = b;
b ^ = a ;
a ^ = b;
有明确定义的行为。
If you write it on a single line, it would appear to be UB since you modify
the variable a twice between sequence points (and even if by some extended
exegesis of the standard it would turn out to be well-defined, it would
still be poor form; but the in the absence of obvious separating sequence
points, the burden to prove well-defined behavior would be on whoever codes
that way. Presumably, it would take a whole paragraph in comments to
justify that line).
However
a ^= b;
b ^= a;
a ^= b;
has well-defined behavior.
我想要这么说。
I wanted to say so.
不,这不是。它只是代码混淆的一种形式。如果你想交换一个
,就这样说:
swap(a,b);
No, it isn''t. It''s just a form of code obfuscation. If you want to swap a
and be, just say so:
swap( a, b );
以及swap的实现是什么?
有人可能希望将int swap作为以上三行来实现。
问候,
FM。
and what is the implementation of swap?
One may like to implement the int swap as the above three lines.
regards,
FM.
如果你在一行上写它,它似乎是UB,因为你在序列点之间修改变量两次(即使是某些
标准的扩展解释它将被证明是明确的,它仍然是不良形式;但是在没有明显分离的序列点的情况下,证明定义明确的行为的负担无论是那种编码的人都会在上面。或许,在评论中需要一整段来证明这条线的合理性。)
然而
^ = b;
b ^ = a;
a ^ = b;
具有明确定义的行为。
If you write it on a single line, it would appear to be UB since you
modify the variable a twice between sequence points (and even if by some
extended exegesis of the standard it would turn out to be well-defined,
it would still be poor form; but the in the absence of obvious separating
sequence points, the burden to prove well-defined behavior would be on
whoever codes that way. Presumably, it would take a whole paragraph in
comments to justify that line).
However
a ^= b;
b ^= a;
a ^= b;
has well-defined behavior.
我想这么说。
I wanted to say so.
不,不是。它只是代码混淆的一种形式。如果你想交换一个
而且,就这么说:
swap(a,b);
No, it isn''t. It''s just a form of code obfuscation. If you want to swap a
and be, just say so:
swap( a, b );
和什么交换的实现?
and what is the implementation of swap?
这取决于库的实现者。
That is up to the implementor of the library.
那又怎样?即使std :: swap应该以这样的方式实现
,它归结为内置标量类型的上述三行,
仍然会并不意味着
a ^ = b; b ^ = a; a ^ = b;
传达的意图也简洁如
std :: swap(a,b);
乱码乱码没有意义。注意:同样适用于
{
int dummy = a;
a = b;
b =虚拟;
}
虽然情况有点弱。您也不想在代码中一遍又一遍地写出
。
Best
Kai-Uwe Bux
So what? Even if std::swap should happen to be implemented in such a way
that it boils down to the above three lines for built-in scalar types, that
still would not imply that
a ^= b; b ^= a; a ^= b;
conveys intend as well and as succinctly as
std::swap( a, b );
There is no point in littering code with hacks. Note: the same applies to
{
int dummy = a;
a = b;
b = dummy;
}
although the case is somewhat weaker. You also would not want to write that
over and over again in your code.
Best
Kai-Uwe Bux
这篇关于在不使用临时变量的情况下交换两个整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!