Почему не отменено одно правило определения для C ++ 17? - PullRequest
0 голосов
/ 08 февраля 2019

Цитирование C ++ Черновик N4713:

Каждая программа должна содержать ровно одно определение каждой не встроенной функции или переменной, которая используется в этой программе посредством odr, за исключением отброшенного оператора (9.4.1);Диагностика не требуется.Определение может явным образом появиться в программе, оно может быть найдено в стандартной или определяемой пользователем библиотеке или (при необходимости) неявно определено (см. 15.1, 15.4 и 15.8).Встроенная функция или переменная должна быть определена в каждой единице перевода, в которой она используется odr, вне исключенного оператора.

В версиях C ++ до C ++ 17 я могу обойти это ограничениепросто объявив мои функции inline.C ++ 17 добавляет ту же функцию для переменных.

Более того, мне кажется, что ключевое слово inline не служит другой цели, кроме возможности игнорировать ODR.

* 1012Итак, почему все это правило не отменено для C ++ 17?Я не вижу цели правила, которое можно отключить.

Ответы [ 4 ]

0 голосов
/ 08 февраля 2019

inline опасно и дорого.

Это дорого, потому что каждая единица компиляции, которая использует что-то, теперь зависит от определения вещи.Так поменять тело?Перекомпилируйте его каждому пользователю.

Это опасно, потому что, если два определения inline не совпадают, ваша программа является IF-NDR (неправильно сформирована, диагностика не требуется).

Без inline,два определения вызывают плохо сформированную программу, но компилятор должен предоставить диагностику;обычно серьезная ошибка.

inline отключает это чрезвычайно полезное предупреждение.

Если каждый компилятор был способен преобразовать IF-NDR различных определений inline в диагностическое сообщение об ошибке, которое выбыло бы больше дела.Пока это оказывается трудным и / или не реализованным, inline является «активировать небезопасный режим!»вариант.Установка по умолчанию будет контрпродуктивной.

0 голосов
/ 08 февраля 2019

«Отключение» ODR с помощью inline не является бесплатным: определение объекта inline должно присутствовать в каждой единице перевода.Обратите внимание, что это подразумевает, что любое изменение в его определении вызывает перекомпиляцию каждого модуля компиляции, который его использует.Это было бы особенно неприятно, когда функция является частью некоторой библиотеки, от которой зависят многие / большие проекты. С другой стороны, функции

Non- inline живут только в одном модуле компиляции и на них ссылаются через некоторый символкомпоновщиком, когда это необходимо в другом месте.Соблюдение ODR гарантирует, что символ не является двусмысленным.

0 голосов
/ 08 февраля 2019

С cppreference :

Одно и только одно определение каждой не встроенной функции или переменной, используемой с помощью odr (см. Ниже), должно отображаться во всемпрограмма (включая любые стандартные и пользовательские библиотеки).Компилятор не обязан диагностировать это нарушение, но поведение программы, которая его нарушает, не определено.

Объявление функции как inline не «игнорирует» ODR, но вызывает каждое появлениефункции, чтобы быть ее собственной сущностью, которая нуждается в определении в каждой единице перевода, где она используется.Небольшая, но значительная разница.ODR по-прежнему должен иметь отдельные переводческие единицы.

0 голосов
/ 08 февраля 2019

Компромисс в том, что вам нужно определение функции inline везде, где она используется.Если вы хотите этого, просто поместите всю программу в один файл .cpp.

ODR - это то, что вам нужно для отдельной компиляции, и это все еще полезно.

...