473,407 Members | 2,312 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

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 1708

"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
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
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
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
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
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
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
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
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
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
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
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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
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
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.