# [SVN] r4250 - trunk/SDL/src/video

Hello !

+#define SWAP(_x, _y) do { int tmp; tmp = _x; _x = _y; _y = tmp; } while (0)

Just personal interest, why is there a
do while(0) loop around the swap function ?

CU

I’ve seen this before and your question sparked/renewed my curiosity. I found
this article that explains why (but someone correctly me if I’m wrong):

http://www.noveltheory.com/TechPapers/while.htm

AlvinOn Saturday 20 December 2008 19:30:07 Torsten Giebl wrote:

Hello !

+#define SWAP(_x, _y) do { int tmp; tmp = _x; _x = _y; _y = tmp; } while
(0)

Just personal interest, why is there a
do while(0) loop around the swap function ?

CU

Hello !

http://www.noveltheory.com/TechPapers/while.htm

Great. Thanks for the link !

CU

I’ve seen this before and your question sparked/renewed my curiosity. I found
this article that explains why (but someone correctly me if I’m wrong):

Yep, that’s it, so that it behaves like a statement. The bit about the
double evaluation can be especially tricky. As well as the bit about
the int, it’s very enjoyable when you put in a long and you lose bits,
but not nearly as enjoyable as finding out the hard way. ;-)On Sat, Dec 20, 2008 at 7:22 PM, Alvin wrote:

Torsten Giebl <wizard syntheticsw.com> writes:

Hello !

+#define SWAP(_x, _y) do { int tmp; tmp = _x; _x = _y; _y = tmp; } while
(0)

Just personal interest, why is there a
do while(0) loop around the swap function ?

CU

When using a define, the function call will be exactly replaced with what the
define statement says. So two calls to the SWAP function after eachother would
result in the tmp variable being declared twice. When using a loop, or if-
statement, or whatever, the variables inside it can’t be called or used outside
the loop and they will be destroyed as soon as the loop/statement ends. So as
soon as the swapping has been performed, the tmp variable will be destroyed
(which brings up the question: “Isn’t it more efficient if you kept the
variable instead of destroying it all the time if you have to swap often?”).

Is ‘static inline’ nonstandard? Wouldn’t that achieve the same effect?

Jonny DOn Sun, Dec 21, 2008 at 12:04 AM, Pierre Phaneuf wrote:

On Sat, Dec 20, 2008 at 7:22 PM, Alvin wrote:

I’ve seen this before and your question sparked/renewed my curiosity. I
found
this article that explains why (but someone correctly me if I’m wrong):

Yep, that’s it, so that it behaves like a statement. The bit about the
double evaluation can be especially tricky. As well as the bit about
the int, it’s very enjoyable when you put in a long and you lose bits,
but not nearly as enjoyable as finding out the hard way.

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Is ‘static inline’ nonstandard? Wouldn’t that achieve the same
effect?

Afaik (I may be wrong:-), ‘inline’ is just a hint to the C compiler,
like ‘register’. It doesn’t guarantee that the function will be indeed
inlined.

Rapha?lOn Dec 21, 2008, at 3:13 PM, Jonathan Dearborn wrote:

Jonny D

On Sun, Dec 21, 2008 at 12:04 AM, Pierre Phaneuf wrote:
On Sat, Dec 20, 2008 at 7:22 PM, Alvin wrote:

I’ve seen this before and your question sparked/renewed my
curiosity. I found
wrong):

Yep, that’s it, so that it behaves like a statement. The bit about the
double evaluation can be especially tricky. As well as the bit about
the int, it’s very enjoyable when you put in a long and you lose bits,
but not nearly as enjoyable as finding out the hard way.

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

inline keyword was add to C99.

Most compilers support it as an extension (GCC has for yonks).

inline is preferrable to any other as it give function symantics (best
namespace seperation etc.) while providing inline performance. do { }
while() gives the closest-to-function symantics in a C89 compatible
way (there are very few full C99 compliant compilers).

inlining doesn’t, necessarily guarantee inline code, but most
compilers will honour it; C/C++ assumes you know what you’ve doing;
they try to warn you about doing dumb things, but if you tell it to do
something specifically, it will do what it’s told, for better or
worse.

Eddy

2008/12/21 Rapha?l Lemoine <lemoine.raphael at gmail.com>:> On Dec 21, 2008, at 3:13 PM, Jonathan Dearborn wrote:

Is ‘static inline’ nonstandard? Wouldn’t that achieve the same effect?

Afaik (I may be wrong:-), ‘inline’ is just a hint to the C compiler, like
’register’. It doesn’t guarantee that the function will be indeed inlined.
Rapha?l

Jonny D

On Sun, Dec 21, 2008 at 12:04 AM, Pierre Phaneuf wrote:

On Sat, Dec 20, 2008 at 7:22 PM, Alvin wrote:

I’ve seen this before and your question sparked/renewed my curiosity. I
found
this article that explains why (but someone correctly me if I’m wrong):

Yep, that’s it, so that it behaves like a statement. The bit about the
double evaluation can be especially tricky. As well as the bit about
the int, it’s very enjoyable when you put in a long and you lose bits,
but not nearly as enjoyable as finding out the hard way.

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Den Sun, 21 Dec 2008 11:12:51 +0000 (UTC)
skrev Creature :

(which brings up the question: “Isn’t it more efficient if you kept
the variable instead of destroying it all the time if you have to
swap often?”).

No. We’ve got optimizing compilers these days, and they’re smart
enough to reuse stack space whenever possible. Eg if you have something
like { int x; } { int y; }, in the second block x is no longer in
scope, so the y variable is free to reuse its space. There’s zero
overhead, no waste of space, and the source code probably ends up
clearer too.

I’d be more worried about the presence of that int there in the first
place. Not really a problem, but it does mean you can only swap ints.
I’m guessing that’s all SDL needs, but anyways, it could be made more
general by using xor swapping in stead to avoid the need for that
temporary variable, ie

#define SWAP(_x,_y) do { _x ^= _y; _y ^= _x; _x ^= y; } while (0)

Won’t work with floats though =]

Oh also, an inline function would be slightly more inconvenient for
this since C passes variables by value, and the swap needs to change
the original variables to work. You’d have to pass pointers to the
variables to swap in stead of the variables themselves.

• Gerry

Den Sun, 21 Dec 2008 11:12:51 +0000 (UTC)
skrev Creature :

(which brings up the question: “Isn’t it more efficient if you kept
the variable instead of destroying it all the time if you have to
swap often?”).

No. We’ve got optimizing compilers these days, and they’re smart
enough to reuse stack space whenever possible. Eg if you have something
like { int x; } { int y; }, in the second block x is no longer in
scope, so the y variable is free to reuse its space. There’s zero
overhead, no waste of space, and the source code probably ends up
clearer too.

I’d be more worried about the presence of that int there in the first
place. Not really a problem, but it does mean you can only swap ints.
I’m guessing that’s all SDL needs, but anyways, it could be made more
general by using xor swapping in stead to avoid the need for that
temporary variable, ie

#define SWAP(_x,_y) do { _x ^= _y; _y ^= _x; _x ^= y; } while (0)

Won’t work with floats though =]

The XOR trick fails silently when _x and _y alias, so it is not equivalent
to the code you are replacing.

-CrystalOn Sun, 21 Dec 2008, Gerry JJ wrote:

Den Sun, 21 Dec 2008 13:31:39 -0800 (PST)
skrev Crystal Jacobs :

The XOR trick fails silently when _x and _y alias, so it is not
equivalent to the code you are replacing.

Damn, I knew I was forgetting something =]. How embarrassing. So
uh, I’ll blame insomnia…

Oh well, there’s still typeof. Though I think that might be
gcc-specific.

• Gerry

Damn, I knew I was forgetting something =]. How embarrassing. So
uh, I’ll blame insomnia…

Oh well, there’s still typeof. Though I think that might be
gcc-specific.

Or you could just use std::swap(). ducks

Just kidding! ;-)On Sun, Dec 21, 2008 at 5:15 PM, Gerry JJ wrote:

Den Sun, 21 Dec 2008 19:20:11 -0500
skrev “Pierre Phaneuf” :

Or you could just use std::swap(). ducks

Hah

again anyway… unless I’m missing something again it’s pretty easy to
get around the alias issue?

#define SWAP(_x,_y) do { if (&(_x) != &(_y)) {
_x ^= _y; _y ^= _x; _x ^= _y; } } while (0)

Since the compiler should always know in advance if the two args are
aliased or not (the args to SWAP should always resolve to some
variables after all) the if test should in theory optimize to a
compile-time constant, right? So actual swaps would then just be the
swap code and aliased “swaps” would be nothing. Only problem is register
vars that can’t be taken address of without putting them in ram first,
but the compiler might be smart enough to realize that since the if
expression is constant anyway there’s no need to do that. Or perhaps
I’m having too much faith in compilers, heh. Haven’t tested this.

Could just compare _x to _y in stead of course and you’d get mostly the
same effect without messing with register vars, but then the expression
wouldn’t be constant anymore and it’d be… less efficient

On the other hand the method using a temporary var is perhaps more
likely to be catched as a swap op and thus the whole thing replaced
spamming, I’m off to bed =]

• Gerry

Den Sun, 21 Dec 2008 19:20:11 -0500
skrev “Pierre Phaneuf” :

Or you could just use std::swap(). ducks

Hah

again anyway… unless I’m missing something again it’s pretty easy to
get around the alias issue?

#define SWAP(_x,_y) do { if (&(_x) != &(_y)) {
_x ^= _y; _y ^= _x; _x ^= _y; } } while (0)

Since the compiler should always know in advance if the two args are
aliased or not (the args to SWAP should always resolve to some
variables after all)

No, because C has pointers. When you use pointers, it does not know in
advance if they may alias unless you use the C99 restrict type-qualifier,
which does not exist in C90 or C++.

[…]

On the other hand the method using a temporary var is perhaps more
likely to be catched as a swap op and thus the whole thing replaced
spamming, I’m off to bed =]

Premature optimization is the root of all weevils.

-CrystalOn Mon, 22 Dec 2008, Gerry JJ wrote:

Den Sun, 21 Dec 2008 20:37:36 -0800 (PST)
skrev Crystal Jacobs :

No, because C has pointers. When you use pointers, it does not know
in advance if they may alias unless you use the C99 restrict
type-qualifier, which does not exist in C90 or C++.

You don’t say =). But we’re not dereferencing pointers anywhere.
We’re doing the opposite, taking the address of two known variables.
(Also, whether or not we dereference pointers to get to those doesn’t
matter.)

union {
int x;
int y;
} u;

&u.x == &u.y

Right? Though I guess you could have a partly aliased one that starts
at a different offset.

Anyway, this is off-topic.

Premature optimization is the root of all weevils.

Absolutely. Kinda ironic that this little derail started with me
replying with essentially this to someone else, huh

• Gerry