Правило одного определения
Вопрос
Что такое ODR, какие нарушения диагностируются, а какие нет, и как inline и шаблоны с ним уживаются?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Ровно одно определение не-inline функции и переменной на программу
Классы, inline-функции, шаблоны: по определению на единицу трансляции, и все одинаковые
Multiple definition: диагностируемое нарушение
Разные определения одного inline или класса: UB без диагностики
Источники: разные макросы и флаги, копипаста имён классов в разных файлах
Средства: безымянные пространства имён, модули, -fsanitize или детекторы ODR в линковщике (gold, lld)
Что могут спросить следом
- Как разные значения NDEBUG могут нарушить ODR?
- Почему два класса Node в разных .cpp опасны?
Разбор
ODR говорит: у каждой не-inline функции и переменной в программе ровно одно определение, а у классов, перечислений, inline-функций и шаблонов определение может быть в каждой единице трансляции, где они используются, но все эти определения обязаны быть одинаковыми по токенам и смыслу. Нарушение первого вида линковщик диагностирует: multiple definition или undefined reference. Нарушение второго вида обычно не диагностируется и является UB. Классический пример: в двух .cpp объявлены разные классы Node с одинаковым именем в глобальном пространстве имён, у обоих inline-конструкторы, линковщик оставит один, и второй файл будет конструировать объект неверного размера. Другой пример: заголовок с inline-функцией, поведение которой зависит от макроса, а макрос в разных файлах разный, или разные флаги вроде _GLIBCXX_DEBUG, меняющие раскладку контейнеров. Защищаюсь так: внутренние классы и функции кладу в безымянное пространство имён, флаги сборки одинаковые для всей программы, а детекторы ODR есть в линковщиках gold и lld и в AddressSanitizer (detect_odr_violation).
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.