473,503 Members | 1,910 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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
Dec 30 '05 #1
5 1711

"Ruben Campos" <ru**********@glup.irobot.uv.es> wrote in message
news:dp**********@peque.uv.es...
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.


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
Dec 30 '05 #2
AD
Another interesting read :
http://pera-software.com/articles/duff-device.pdf

Dec 30 '05 #3
<ru**********@glup.irobot.uv.es> wrote:
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.


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. ]
Dec 30 '05 #4
Ruben Campos wrote:
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?


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.
Dec 30 '05 #5
"Ruben Campos" <ru**********@glup.irobot.uv.es> wrote in message
news:dp**********@peque.uv.es...
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


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...

Jan 2 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
4838
by: Jonas | last post by:
This works fine in Win XP but does not work at all in Win 98. Private WithEvents objIExplorer As InternetExplorer I have to do it like this to get it to work in Win 98 Dim objIExplorer As...
3
3728
by: Julian | last post by:
Hi I am trying to update a date field in my table but some how this simple code does not work, I know the select work because if I write the fields, it will show the data from the table but why...
5
3593
by: me | last post by:
I have a Class Library that contains a Form and several helper classes. A thread gets created that performs processing of data behind the scenes and the Form never gets displayed (it is for debug...
22
2569
by: Robert Bralic | last post by:
CAN anybody tell me any address where I can download some small(1000-2000) lines C++ proghram source. Or send me ,a small(1000-2000) lines C++ program source that I can compille with gpp under...
12
2916
by: Frank Hauptlorenz | last post by:
Hello Out there! I have a DB2 V7.2 Database (Fix11) on Win 2000 Professional. It was before a NT 4 based Domain - now it is a Win 2000 Domain. The database server is a domain member. Now...
0
2342
by: Jarod_24 | last post by:
How does tabindex work in ASP .net pages I dosen't seem to work quite like in regular forms. and there isn't any TabStop property either. 1 .How do you prevent a control form beign "tabbed"....
14
4814
by: Anoop | last post by:
Hi, I am new to this newsgroup and need help in the following questions. 1. I am workin' on a GUI application. Does C# provides Layout Managers the way Java does to design GUI? I know that it...
89
5948
by: Cuthbert | last post by:
After compiling the source code with gcc v.4.1.1, I got a warning message: "/tmp/ccixzSIL.o: In function 'main';ex.c: (.text+0x9a): warning: the 'gets' function is dangerous and should not be...
14
3450
by: webEater | last post by:
I have a problem, it's not browser specific, and I don't get a solution. I have an (X)HTML document, I show you a part of it: .... <!--<div class="pad">--> <div id="eventImages"><img src=""...
1
7078
by: =?ISO-8859-1?Q?Lasse_V=E5gs=E6ther_Karlsen?= | last post by:
I get the above error in some of the ASP.NET web applications on a server, and I need some help figuring out how to deal with it. This is a rather long post, and I hope I have enough details that...
0
7287
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7006
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7467
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5592
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4685
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3166
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
744
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
397
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.