Skip to content

Duff's Device It looks weird and wtf is even going on

send(to, from, count)
register short *to, *from;
register count;
{
    register 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);
    }
}

First: What Problem Is Duff’s Device Solving?

Suppose you want to copy count values from one array to another:

for (int i = 0; i < count; i++) {    *to = *from++;    to++;}

Simple.

But on older hardware:

  • loop overhead was expensive
  • branches were expensive
  • CPUs were slow

So programmers used loop unrolling.

Instead of copying 1 item per iteration:

while (count--) {    *to++ = *from++;}

you copy several at once:

while (count >= 8) {    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;    count -= 8;}

Now the loop branch happens once every 8 copies instead of every copy.

That’s the basic idea.

The Remaining Problem

What if the number isn't divisible by 8?

Example:

  • count = 13

You can do:

  • 8 copies in one full loop
  • but now 5 remain

Normally you'd write cleanup code:

while (count--) {    *to++ = *from++;}

Duff’s Device merges:

  • the unrolled loop
  • and the cleanup logic

into one bizarre structure.

Key Insight #1 — case Labels Are Just Labels

People imagine:

switch(x) {    case 1:}

creates some special structure.

It mostly doesn’t.

A case label is basically:

  • a jump target
  • attached to a statement

That’s why this is legal:

switch(x)    case 1:        printf("hello");

No braces required.

And labels can exist inside nested blocks.


Key Insight #2 — Fallthrough Is Legal

Normally:

switch(x) {case 1:    foo();case 2:    bar();}

If x == 1, execution continues into case 2.

No automatic stopping occurs.

C switch statements are basically:

computed goto + labels + optional breaks


Key Insight #3 — do/while Executes First, Checks Later

A do/while loop:

do {    stuff();} while(condition);

always runs the body at least once.

This becomes crucial.


Now Let’s Trace It Slowly

Suppose:

count = 13

Step 1 — Calculate Number Of Loop Iterations

n = (count + 7) / 8;

Why?

Integer division rounds down.

So:

(13 + 7) / 8= 20 / 8= 2

Meaning:

  • we need 2 iterations
  • each can copy up to 8 values

Step 2 — Determine Entry Point

switch(count % 8)
13 % 8 = 5

So execution jumps to:

case 5:

NOT the top.

This is the horrifying part.

Execution enters the middle of the loop body.


Step 3 — First Iteration Begins Midway

We jump directly here:

case 5:    *to = *from++;case 4:    *to = *from++;case 3:    *to = *from++;case 2:    *to = *from++;case 1:    *to = *from++;

How many copies happened?

Cases:

  • 5
  • 4
  • 3
  • 2
  • 1

Total:

5 copies

Perfect.
That handles the leftover remainder.


Step 4 — Reach Bottom Of Loop

Now we hit:

} while (--n > 0);

Currently:

n = 2

After decrement:

n = 1

Condition true.

Loop continues.


Step 5 — Second Iteration Starts At TOP

This is the clever bit.

The second iteration does NOT re-enter via the switch.

The switch already happened.

Now control loops normally to the top of the do.

So execution begins here:

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++;

Since there are no breaks:

  • all 8 execute

Total:

8 copies

Total Accounting

First partial iteration:

5 copies

Second full iteration:

8 copies

Total:

13 copies

Exactly correct.


The Mental Model

Duff’s Device works by:

  1. entering an unrolled loop halfway through
  2. finishing the partial chunk
  3. looping normally afterward

It combines:

  • remainder handling
  • full loop processing

into one control structure.


Why This Is Legal

Because C allows:

  • labels inside blocks
  • switch labels attached to arbitrary statements
  • fallthrough
  • looping around labels

Nothing in the standard forbids:

  • jumping into the middle of a loop body

So this monstrous thing is valid.


What The Compiler Sees

Conceptually something like:

if remainder == 5:    goto LABEL5LOOP_TOP:    copyLABEL7:    copyLABEL6:    copyLABEL5:    copyLABEL4:    copyLABEL3:    copyLABEL2:    copyLABEL1:    copyif (--n > 0)    goto LOOP_TOP

Once viewed this way, it becomes much less magical.

It’s basically hand-written control flow manipulation.


Why It Was Famous

Duff’s Device became legendary because it revealed:

  • how permissive C’s control flow really is
  • how deeply programmers understood machine costs
  • how “high-level language” abstractions could be bent

It feels like:

  • switch abuse
  • goto abuse
  • loop abuse

all simultaneously.

And yet:

  • elegant
  • efficient
  • fully legal

Which is peak C.