Автор подбросил сообществу языков программирования C и C++ сложную загадку с выражением, приводящим к неопределённому поведению. Комбинация операций предварительного и отложенного инкремента (++, --) в одном выражении оставляет компилятору полную свободу действий, что породило три возможных правильных ответа: 11, 12 или 13. Теоретический анализ показывает, что проблема возникает сразу в двух местах. Сначала компилятору неизвестно, когда он загрузит значение переменной в регистр: либо это произойдёт до её инкремента, либо после. Если загрузка первой копии происходит первой, результат складывается как 5 плюс 6, давая 11. Если же преинкремент выполняется прежде, оба слагаемых становятся равны 6, и сумма равна 12. Второй источник неопределённости связан с самим механизмом постинкремента. В некоторых реализациях обновлённое значение в памяти перезаписывается раньше, чем результат операции вычитается, из-за чего прирост теряется. В иных случаях увеличение происходит в самом конце вычислений и не затевается. Эти два фактора комбинируются, порождая все три результата.
Эмпирические тесты, проведённые разработчиком nism0 и расширенные польскими энтузиастами, подтвердили разнообразие ответов от разных систем. Версии GCC от 2.95 до 4.6.0 выдавали на первых трёх тестах результаты 12, 13 и 14. Минимальная версия TCC и BCC возвращали «неизвестные» значения для сложных случаев, но 5 и 12 для простых. Компиляторы Microsoft и Embarcadero стабильно выдавали 12, 13 и 13. Старые версии Keil C, SDCC и clang также вносили свой вклад в статистику. Даже специфические компиляторы для ZX Spectrum или старые версии Turbo C++ давали свои результаты. Отдельный интерес вызвало поведение с перегрузкой операторов в MSVC++, где результат менялся на 11 и 12. Анализы спецификаций C# и Java показали, что там поведение строго определено слева направо, и загадки нет. Экспериментальный код, созданный nism0, позволяет проверить свой компилятор самостоятельно. Авторы отметили, что уровень оптимизации и выбор архитектуры процессора могут влиять на частоту обращения к памяти, изменяя итоговый результат в языках с неопределённым поведением.
В комментариях пользователи обсуждали, как перегрузка операторов влияет на результаты в MSVC++ и GCC. Автор также порекомендовал изучить статью о точках последовательности для понимания порядка вычислений. Кроме того, в рамках отдельного события проходили обучение работе с бинарными файлами и протоколами. В заключение стоит отметить, что эта проблема — классический пример того, как строгое следование стандарту может быть сложно предсказать на практике, если язык допускает неопределённое поведение. Разработчики должны избегать таких конструкций или явно определять порядок вычисления, чтобы избежать недоразумений, которые зависят от конкретного компилятора.