Duff device syntax revision - is it legal C / C ++?

Just yesterday, I first met the curious Duff device . I read about it, and I don’t think it’s hard to understand. I am interested in the strange syntax (from Wikipedia):

register short *to, *from; register int count; { register int n = (count + 7) / 8; switch(count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while(--n > 0); } } 

I read the standard definition of the C ++ operator (let me know if this is deprecated, I am not familiar with Open-Std.org). As I understand it, case statements are simply simplified branch instructions for use by the switch statement.

The switch itself completely ignores the nested do-while, and the loop ignores case statements. Since the switch jumps inside the loop, the loop executes. The switch should close the remainder (dividing by 8), and the loop processes the part that is evenly divided. All this makes sense.

Then my question is why the syntax is awkward? It occurs to me that a cycle can be written so that all the statements of the case are contained inside, right? I don’t see anything in the standard that prohibits this behavior, and it compiles correctly in accordance with GCC 4.7, so what is considered legal next?

 register short *to, *from; register int count; { register int n = (count + 7) / 8; switch (count <= 0 ? 8 : count % 8) { do { case 0: *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; default: ; // invalid count, suppress warning, etc. } while(--n > 0); } } 

For me, this makes the code much clearer. Thanks for any feedback .;)

Edit: As indicated below, the source code was written for C and had an implicit int for count and n variables. Since I marked it in C ++, I changed this.

Edit 2: The revised example code has been changed to account for invalid account values.

+8
c ++ switch-statement
source share
3 answers

Looking at the C ++ 11 standard, the part of the code that I think you are asking about will be resolved. Have you tried this?

The rule that I see is most applicable:

Note. Typically, the subtitle that is the object of the switch is compound, and the case and default labels appear in the top-level statements contained in the (compound), but this is not required.

This actually means that you can get rid of the curly braces around do - while and write

  int n = (count + 7) / 8; switch (count % 8) do { case 0: *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while(--n > 0); 

However, this line is NOT valid C ++:

 register n = (count + 7) / 8; 

C ++ does not allow default-int, the type of the variable must be specified or deduced.


Oh, fix the number of iterations without breaking the formatting:

  int n = 1 + count / 8; switch (count % 8) do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; case 0: ; } while(--n > 0); 
+8
source share

Yes, it is legal. The labels of the switch are usually written at the same level as the switch . However, it is legal to write them inside compound statements, for example. in the middle of a cycle.

EDIT : There is no requirement that the body of a switch statement starts with a label, any code is legal. However, there is no way into it from the switch statement itself, so if it is not a loop or a simple label, the code will not be available.

Another interesting thing with the swtich operator is that curly braces are optional. However, in this case, only one label is allowed:

  switch (i) case 5: printf("High five\n"); 
+1
source share

The code is certainly legal: there are no requirements for blocks and / or loops. However, it should be noted that count == 0 not correctly processed by the above loop. It is, however, correctly handled by this:

 int count = atoi(ac == 1? "1": av[1]); switch (count % 4) { case 0: while (0 < count) { std::cout << "0\n"; case 3: std::cout << "3\n"; case 2: std::cout << "2\n"; case 1: std::cout << "1\n"; count -= 4; } } 

Putting the label case 0 inside the loop will also incorrectly execute nested statements. Although I saw that the Duff device always uses a do-while , it seems that the above code is more natural for solving the boundary condition.

+1
source share

All Articles