1

So at our university, they've been printing out the following piece of code on the coffee cups :

void f(char *x, char*y, int z)
{
    int z2 = (z + 7) / 8;
    switch (z % 8)
    {
        case 0:
        do 
        {
            *x++ = *y++;
        case 7:
            *x++ = *y++;
        case 6:
            *x++ = *y++;
        case 5:
            *x++ = *y++;
        case 4:
            *x++ = *y++;
        case 3:
            *x++ = *y++;
        case 2:
            *x++ = *y++;
        case 1:
            *x++ = *y++;
            } while (--z2 > 0);
    }
}

Running it, I've figured out it just copies z bytes from the address pointed to by y, into the address pointed to by x. It seems to me as if the code is just needlessly complicated and ugly , with the switch statement and especially the confusing do while loop beginning in case 0 and ending in case 1. Wouldn't a simple for loop suffice ? :

void ff(char *x, char *y, int z)
{
    for (int i = 0; i < z; i++)
        *x++ = *y++;
}

As far as I could tell, it does the same thing, unless there's something I'm missing?

alex-tdrn
  • 31
  • 5

1 Answers1

11

You're missing that this is famous, it's called Duff's device. I would say it's mainly of interest to code historians and language lawyers.

It's a good example of unexpected but valid C syntax, which makes it interesting. It's also a valid way to optimize a copying loop, essentially unrolling it manually, instead of relying on the compiler to do so.

With modern compilers, I'd expect this to be pointless, but I haven't tested it. The Wikipedia page hints at it being pointless in current code.

It's (of course) quite clearly harder to understand than the equivalent simple byte-copying loop, so that's a big minus. I would not be happy if it turned up in code I review. :)

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 2
    This should be a comment – Federico klez Culloca May 23 '17 at 12:48
  • 9
    This is a perfectly valid answer. – Walter May 23 '17 at 12:50
  • 1
    @FedericoklezCulloca this shouldnt be a comment, because any attempt to answer the question should not go into comments. If it was a comment you werent able to downvote it (and I could not upvote it :P) – 463035818_is_not_an_ai May 23 '17 at 12:51
  • I'd rather call it infamous. Duff's device, which is nothing but a method of pre-mature optimization (through obfuscation), should be completely obsolete nowadays. – Lundin May 23 '17 at 12:53
  • 1
    @tobi303 IMHO this shouldn't be an answer because there was no question to begin with (I voted to close as "unclear what's being asked"). I don't really understand this site anymore: technical questions go down as OT, people go crazy when someone answers to a question that has a duplicate, but this answer is ok? Not trying to be argumentative, just genuinely curious. – Federico klez Culloca May 23 '17 at 12:55
  • 4
    @FedericoklezCulloca Sorry to upset you. I saw "unless there's something I'm missing?" as a literal question, which was answerable by naming the well-known construct, and also explaining why it was created. I don't think it's that strange. – unwind May 23 '17 at 12:57
  • @unwind, I'm not upset, just a bit puzzled – Federico klez Culloca May 23 '17 at 12:58
  • @FedericoklezCulloca the question could be a bit more clear, but "Is there any difference between my code and the code on the cup" is rather clear imho and a valid question. The only thing I would critizise on this answer that it does not refer to OPs version of the code, but otherwise it is fine imho. Btw as long as different users can have different opinions and are able to express them freely SO is just fine. – 463035818_is_not_an_ai May 23 '17 at 13:01
  • I could have been more clear, I was confused why one would chose the longer version, and seeing as I have never heard of Duff's device before, this clears it up quite well, thanks! – alex-tdrn May 23 '17 at 13:25