Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old December 30th, 2005, 03:15 PM
Ruben Campos
Guest
 
Posts: n/a
Default Why does it work?

Greetings.

I was recently reading the article "Typed buffers (II)", by Andrei
Alexandrescu (C/C++ Users Journal, October 2001), and I found the next
function in it:

template <class T> inline void FillDuff
(T* begin, T* end, const T& obj)
{
switch ((end - begin) & 7)
{
case 0:
while (begin != end)
{
*begin = obj; ++begin;
case 7: *begin = obj; ++begin;
case 6: *begin = obj; ++begin;
case 5: *begin = obj; ++begin;
case 4: *begin = obj; ++begin;
case 3: *begin = obj; ++begin;
case 2: *begin = obj; ++begin;
case 1: *begin = obj; ++begin;
}
}
}

After reading Andrei's explanation and analyzing the code for a while, I
understood the way it works. Also, I tried it in order to see it myself,
and everything was right. But I still do not understand why that code
even compiles, so I would be very grateful if someone could throw some
light.

From my point of view, when the execution thread initially reaches the
"switch" sentence the remainder is computed, and a jump is performed to
the corresponding "case". Being the remainder not null, why is the
"while" sentence executed? Tracing with MSVC 7.1 shows the expected jump
from "switch" directly to the corresponding "case" line, without
evaluating the "while" condition. But after executing until the last
case, it reaches the "while" closing bracket and then jumps back to
continue with the "while" loop. Until now, I believed the only way to
enter a "while" loop was through its initial "while" sentence.

I supposed this could be discussed when published, so I apologize if
coming back again over an already treated matter. Thank you in advance.

Rubén Campos
  #2  
Old December 30th, 2005, 03:25 PM
Mike Wahler
Guest
 
Posts: n/a
Default Re: [link] Why does it work?


"Ruben Campos" <ruben.campos@glup.irobot.uv.es> wrote in message
news:dp3i1g$dvv$1@peque.uv.es...[color=blue]
> Greetings.
>
> I was recently reading the article "Typed buffers (II)", by Andrei
> Alexandrescu (C/C++ Users Journal, October 2001), and I found the next
> function in it:
>
> template <class T> inline void FillDuff
> (T* begin, T* end, const T& obj)
> {
> switch ((end - begin) & 7)
> {
> case 0:
> while (begin != end)
> {
> *begin = obj; ++begin;
> case 7: *begin = obj; ++begin;
> case 6: *begin = obj; ++begin;
> case 5: *begin = obj; ++begin;
> case 4: *begin = obj; ++begin;
> case 3: *begin = obj; ++begin;
> case 2: *begin = obj; ++begin;
> case 1: *begin = obj; ++begin;
> }
> }
> }
>
> After reading Andrei's explanation and analyzing the code for a while, I
> understood the way it works. Also, I tried it in order to see it myself,
> and everything was right. But I still do not understand why that code even
> compiles, so I would be very grateful if someone could throw some light.
>
> From my point of view, when the execution thread initially reaches the
> "switch" sentence the remainder is computed, and a jump is performed to
> the corresponding "case". Being the remainder not null, why is the "while"
> sentence executed? Tracing with MSVC 7.1 shows the expected jump from
> "switch" directly to the corresponding "case" line, without evaluating the
> "while" condition. But after executing until the last case, it reaches the
> "while" closing bracket and then jumps back to continue with the "while"
> loop. Until now, I believed the only way to enter a "while" loop was
> through its initial "while" sentence.
>
> I supposed this could be discussed when published, so I apologize if
> coming back again over an already treated matter. Thank you in advance.[/color]

This has indeed been discussed at great length by
some folks, but mostly in a C context, so using
only C++, you might or might not have heard of
"Duff's Device":

http://www.lysator.liu.se/c/duffs-device.html

-Mike


  #3  
Old December 30th, 2005, 06:15 PM
AD
Guest
 
Posts: n/a
Default Re: Why does it work?

Another interesting read :
http://pera-software.com/articles/duff-device.pdf

  #4  
Old December 30th, 2005, 09:45 PM
Roberto Waltman
Guest
 
Posts: n/a
Default Re: Why does it work?

<ruben.campos@glup.irobot.uv.es> wrote:[color=blue]
>I was recently reading the article "Typed buffers (II)", by Andrei
>Alexandrescu (C/C++ Users Journal, October 2001), and I found the next
>function in it:
>
>template <class T> inline void FillDuff
> (T* begin, T* end, const T& obj)
>{
> switch ((end - begin) & 7)
> {
> case 0:
> while (begin != end)
> {
> *begin = obj; ++begin;
> case 7: *begin = obj; ++begin;
> case 6: *begin = obj; ++begin;
> case 5: *begin = obj; ++begin;
> case 4: *begin = obj; ++begin;
> case 3: *begin = obj; ++begin;
> case 2: *begin = obj; ++begin;
> case 1: *begin = obj; ++begin;
> }
> }
>}
>
>After reading Andrei's explanation and analyzing the code for a while, I
>understood the way it works. Also, I tried it in order to see it myself,
>and everything was right. But I still do not understand why that code
>even compiles, so I would be very grateful if someone could throw some
>light.[/color]

It is a well know idiom (or "trick"?) in the C language.
Search for "Duff's device." I do believe that in an
ideal world that code should not compile, but on this
one that is legal C/C++.

Roberto Waltman

[ Please reply to the group, ]
[ return address is invalid. ]
  #5  
Old December 30th, 2005, 11:25 PM
Ron Natalie
Guest
 
Posts: n/a
Default Re: Why does it work?

Ruben Campos wrote:
[color=blue]
> From my point of view, when the execution thread initially reaches the
> "switch" sentence the remainder is computed, and a jump is performed to
> the corresponding "case". Being the remainder not null, why is the
> "while" sentence executed?[/color]

You can jump into the middle of a while statement and it will
continue to iterate:

goto foo;
while(condition) {
foo:
statement;
}

the only thing you can't do with either switch or goto is jump over
initializations.
  #6  
Old January 2nd, 2006, 08:35 PM
Jim Langston
Guest
 
Posts: n/a
Default Re: Why does it work?

"Ruben Campos" <ruben.campos@glup.irobot.uv.es> wrote in message
news:dp3i1g$dvv$1@peque.uv.es...[color=blue]
> Greetings.
>
> I was recently reading the article "Typed buffers (II)", by Andrei
> Alexandrescu (C/C++ Users Journal, October 2001), and I found the next
> function in it:
>
> template <class T> inline void FillDuff
> (T* begin, T* end, const T& obj)
> {
> switch ((end - begin) & 7)
> {
> case 0:
> while (begin != end)
> {
> *begin = obj; ++begin;
> case 7: *begin = obj; ++begin;
> case 6: *begin = obj; ++begin;
> case 5: *begin = obj; ++begin;
> case 4: *begin = obj; ++begin;
> case 3: *begin = obj; ++begin;
> case 2: *begin = obj; ++begin;
> case 1: *begin = obj; ++begin;
> }
> }
> }
>
> After reading Andrei's explanation and analyzing the code for a while, I
> understood the way it works. Also, I tried it in order to see it myself,
> and everything was right. But I still do not understand why that code even
> compiles, so I would be very grateful if someone could throw some light.
>
> From my point of view, when the execution thread initially reaches the
> "switch" sentence the remainder is computed, and a jump is performed to
> the corresponding "case". Being the remainder not null, why is the "while"
> sentence executed? Tracing with MSVC 7.1 shows the expected jump from
> "switch" directly to the corresponding "case" line, without evaluating the
> "while" condition. But after executing until the last case, it reaches the
> "while" closing bracket and then jumps back to continue with the "while"
> loop. Until now, I believed the only way to enter a "while" loop was
> through its initial "while" sentence.
>
> I supposed this could be discussed when published, so I apologize if
> coming back again over an already treated matter. Thank you in advance.
>
> Rubén Campos[/color]

Because of the way a while statement is translated into assembly. In pseudo
code it would look something like (not exactly and I may be off, just trying
to show the logic).

while ( a != b )
{
// do something
};

would become something like:

:whiletag
compare a, b
if a == b goto end
// do something
goto whiletag
:end

Now, you see if you jump into // do something, the next statement is goto
whiletag which does the compare, etc...





 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles