одно правило определения — делают ли модули C ++ нарушения ODR отсутствующими?

От N4720 Проект модулей C ++, [basic.def.odr] / 6 говорит:

[…] Для объекта с экспортированной декларацией должно быть только одно определение этого объекта; диагностика требуется только в том случае, если граф абстрактной семантики модуля содержит определение сущности. [Заметка: Если определение отсутствует в интерфейсном модуле, то самое большее один модуль может иметь и использовать определение. — конец примечания] […]

Что, насколько я понимаю, практически дает возможность шаблонам анализироваться компилятором только один раз, в отличие от текущего положения дел (наличие точной копии их определений на единицу перевода). Это также верно для других объектов с похожим регистром, таких как встроенные функции / переменные.

Мой вопрос возник из-за того, что, поскольку вы можете иметь не более одного определения сущностей (как описано в [Basic.def.odr] / 1) для каждой единицы перевода неопределенное поведение — иметь разные определения сущности в разных TU. И, поскольку экспортируемые сущности должны иметь только одно определение во всем модуле компиляции (делая неэкспортированные объекты уникальными для их модуля реализации), получить неправильное определение, с моей точки зрения, сложнее, если не невозможно.

Наконец, проще говоря: сделает ли (или делает, или должен) использование модулей невозможным нарушение правил ODR или иным образом сложнее ошибиться?

5

Решение

Если проект от корки до корки модульный (то есть, никогда не использует #include), тогда большинство случайных нарушений ODR исчезнет. Большинство случайных нарушений ODR происходят из-за характера #include: включая глобальную переменную с определением и так далее. Или проблемы поиска двухфазных шаблонов, когда два файла содержат один и тот же шаблон, но из-за того, что каждый из них был включен в этот шаблон, определение двух шаблонов отличается.

Однако это никак не предотвращает менее «случайные» нарушения УСО. Поскольку «та же сущность» определяется ее именем, а имя сущности не имеет ничего общего с модулем, из которого она была экспортирована, два модуля могут предоставлять разные определения одной и той же сущности. Так что в основном, назовите коллизии.

Это становится только ошибкой компиляции (т.е. требуется диагностика), если один модуль перевода импортирует оба таких модуля. Если каждый из двух отдельных модулей перевода включает в себя один из модулей с разными определениями, то программа в целом все еще нарушает ODR, но в этом нет необходимости проводить диагностику.

Таким образом, даже в полностью модульной кодовой базе ODR все еще может быть нарушен.

3

Другие решения

Других решений пока нет …