встроенная функция может быть определена в программе несколько раз, если определения идентичны
Нет («Идентичный» здесь даже не является четко определенным понятием.)
Формально определения должны быть эквивалентными в каком-то очень строгом смысле, который даже не имеет смысла как требование и который никого не волнует:
// in some header (included in multiple TU):
const int limit_max = 200; // implicitly static
inline bool check_limit(int i) {
return i<=limit_max; // OK
}
inline int impose_limit(int i) {
return std::min(i, limit_max); // ODR violation
}
Такой код вполне разумен, но формально нарушает одно правило определения:
в каждом определении D соответствующие имена, найденные в соответствии с 6.4 [basic.lookup], должны ссылаться на объект, определенный в определении D, или должны ссылаться на тот же объект после разрешения перегрузки (16.3 [over.match] ) и после сопоставления частичной специализации шаблона (17.9.3 [temp.over]), за исключением того, что имя может относиться к константному объекту с внутренней связью или без связи, если объект имеет один и тот же литеральный тип во всех определениях D, и объект инициализируется постоянным выражением (8.20 [expr.const]), и используется значение (но не адрес) объекта, и объект имеет то же значение во всех определениях D ;
Поскольку исключение не позволяет использовать константный объект с внутренней связью (const int
неявно статичен) с целью прямой привязки константной ссылки (а затем использования ссылки только для ее значения). Правильная версия:
inline int impose_limit(int i) {
return std::min(i, +limit_max); // OK
}
Здесь значение limit_max
используется в унарном операторе +, а тогда константная ссылка привязывается к временной инициализации с этим значением. Кто на самом деле так делает?
Но даже комитет не верит в формальные вопросы ODR, как мы видим в Основная проблема 1511:
1511. переменные const volatile и правило одного определения
Раздел: 6.2 [basic.def.odr] Статус: CD3 Отправитель: Ричард Смит Дата: 18.06.2012
[Перемещено в DR на собрании в апреле 2013 г.]
Эта формулировка, возможно, недостаточно ясна для такого примера, как:
const volatile int n = 0;
inline int get() { return n; }
Мы видим, что комитет считает, что это вопиющее нарушение намерений и целей ODR, как написано, кода, который считывает разные изменчивые объекты в каждом TU, то есть код, который имеет видимый побочный эффект на другом объекте, поэтому другой видимый побочный эффект в порядке, потому что мы не заботимся о том, что именно .
Важно то, что эффект встроенной функции неопределенно эквивалентен: выполнение volatile int read, что является очень слабым эквивалентом, но достаточным для естественного использования ODR, что является безразличием экземпляра : какой именно экземпляр встроенной функции используется, не имеет значения и не может иметь значения.
В частности, значение, считываемое при чтении volatile, по определению не известно компилятору, поэтому условие публикации и инварианты этой функции, анализируемые компилятором, совпадают.
При использовании разных определений функций в разных TU необходимо убедиться, что они строго эквивалентны с точки зрения вызывающего: что никогда не удастся удивить вызывающего, заменив одно на другое. Это означает, что наблюдаемое поведение должно быть строго одинаковым, даже если код отличается.
Если вы используете другие параметры компилятора, они не должны изменять диапазон возможных результатов функции (возможно, с точки зрения компилятора).
Поскольку «стандарт» (который на самом деле не является спецификацией языка программирования) позволяет объектам с плавающей запятой иметь реальное представление, не разрешенное их официально объявленным типом, совершенно неограниченным образом, используя любой не изменчивый квалифицированный тип с плавающей запятой в все, что многократно определяется в соответствии с ODR, кажется проблематичным, если вы не активируете режим «double
означает double
» (который является единственным нормальным режимом).
person
curiousguy
schedule
30.11.2018
sum(2,2)
дает 4, в другом - 5. Я не вижу здесь неопределенного поведения, - person Alex F   schedule 28.08.2018