Перед вами один из самых знаменитых и «вирусных» фрагментов кода на C за всю историю языка.

На первый взгляд кажется, что это синтаксическая ошибка — ведь здесь switch буквально переплетён с циклом do-while. Но нет, это абсолютно валидный, стандартный C-код!

void fastCopy(short* to, short* from, int count) 
{
		if (count <= 0) return;

    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);
    }
}

Что это вообще такое?

Приём назван в честь Тома Даффа, который придумал его в 1983 году, работая в Lucasfilm Computer Division — подразделение, из которого позже вырос Pixar.

Его задача была ускорить копирование данных при работе над программой для анимации и он нашёл элегантное и слегка безумное решение, которое сочетает в себе механизм switch и раскрутку цикла loop unrolling

Зачем так делать?

Это классический приём раскрутки цикла (loop unrolling) для оптимизации копирования памяти. Идея простая:

  1. Экономия на проверках: в обычном цикле на каждую итерацию приходится проверка условия и переход — это накладные расходы. Здесь за одну итерацию выполняется сразу 8 копирований, а проверка --n > 0 срабатывает в 8 раз реже
  2. Элегантная обработка «остатка»: обычно при развёртке цикла приходится отдельно дописывать код для обработки элементов, которые «не влезли» в кратную порцию (например, если нужно скопировать 20 элементов, а цикл развёрнут по 8). switch в начале служит точкой входа, которая отправляет выполнение прямо на нужную итерацию, чтобы обработать остаток (count % 8), а затем переходит к полным циклам

В чём магия?

Секрет в том, что в C метки case — это, по сути, обычные метки для перехода, и они могут находиться внутри вложенных блоков.

Полный листинг

https://godbolt.org/z/3x94PhzsY

#include <stdio.h>

void fastCopy(short *to, short *from, int count) 
{
		if (count <= 0) return;
    
    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);
    }
}

int main(void) 
{
    short src[20]  = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    short dest[20] = {0};

    fastCopy(dest, src, 20);

    printf("Source array: ");
    for (int i = 0; i < 20; ++i) 
    {
        printf("%d ", src[i]);
    }
    printf("\\n");

    printf("Copied array: ");
    for (int i = 0; i < 20; ++i) 
    {
        printf("%d ", dest[i]);
    }
    printf("\\n");

    return 0;
}

⚡ А актуально ли это сегодня?

Скорее нет, чем да. Современные компиляторы сами разворачивают циклы и применяют SIMD-инструкции. Более того, Duff's Device нередко мешает векторизации и может оказаться медленнее обычного memcpy.