Одно правило определения: могут ли соответствующие объекты иметь разные имена?

Я прочитал и перечитал соответствующие статьи об ODR в стандарте C ++, но этот вопрос все еще остается для меня открытым. Стандарт говорит, что определение встроенной функции должно появляться в каждой единице перевода, в которой она используется, и определения должны быть идентичными в том смысле, который описан почти на странице. В нем говорится, что последовательность токенов должна быть такой же. Включает ли он имена локальных идентификаторов?

Другими словами, нарушает ли следующая программа ODR? (я сам пытался протестировать ее с помощью Visual Studio 2008 и получил 0 ошибок и 0 предупреждений. Но я полагаю, что это не так » Я ничего не могу доказать, потому что затем я изменил пример на два совершенно разных определения и по-прежнему получил 0 ошибок и 0. Извиняясь за MSVC, следует отметить, что формально диагностика нарушений ODR не требуется).

//main.cpp
inline int f(int);
int main(){
   f(3);
}
int f(int x){
   int z = x;
   return z*z;
}

//other.cpp
inline int f(int xx){
   int zz = xx;
   return zz*zz;
}

person Armen Tsirunyan    schedule 28.11.2010    source источник
comment
@fred: Разве C не имеет встроенной функции и ODR?   -  person Armen Tsirunyan    schedule 28.11.2010
comment
Оно делает? Тогда смело откатывайтесь. Я хотя встроенные функции были только C ++.   -  person fredoverflow    schedule 28.11.2010
comment
Да ладно, ребята, я не могу слепо поверить в ответ. Если вы согласны с каким-либо ответом, пожалуйста, проголосуйте за него :)   -  person Armen Tsirunyan    schedule 28.11.2010
comment
@Fred C на самом деле не имеет ODR в смысле C ++. Но см. встроенный C99 для строковое значение в C99.   -  person Johannes Schaub - litb    schedule 28.11.2010


Ответы (3)


Идентификатор - это своего рода токен, каждый идентификатор - это отдельный токен, поэтому да, вам нужно иметь один и тот же идентификатор для соблюдения ODR. Это может иметь значение для компилятора, который это обнаруживает (кто-то готов создать пример для como с экспортированным шаблоном? Он может обнаружить некоторые нарушения ODR).

Тогда здесь есть разница между C и C ++. C вообще не имеет ODR, и правила для встроенных функций в C99 (в C90 нет встроенных функций) сильно отличаются от правил C ++. В C99 ваш код правильный. На самом деле вы можете дать совершенно другое определение. Следствием этого является то, что в C (но не в C ++), если вы используете то же определение и это определение имеет статический член, у вас фактически столько же статических переменных, сколько TU, использующих функцию.

person AProgrammer    schedule 28.11.2010
comment
+1, но, возможно, вы могли бы прояснить последнее предложение (в настоящее время похоже, что оно может описывать C или C ++). - person j_random_hacker; 28.11.2010
comment
Что касается статических объектов во встроенных функциях C, обратите внимание, что в стандарте говорится: Встроенное определение функции с внешней связью не должно содержать определения изменяемого объекта со статической продолжительностью хранения и не должно содержать ссылку на идентификатор с внутренней связью. - person caf; 29.11.2010

Да, это нарушает ODR. Он использует разные последовательности токенов, потому что x - это токен, отличный от xx. Это так просто. Хотя в нем могут быть разные пробелы или комментарии, поскольку это не токены.

Проверка ODR по единицам перевода с помощью традиционного инструментария компиляции практически невозможна. В стандарте говорится, что диагностика не требуется, поэтому вы просто получаете неопределенное поведение.

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

person Yakov Galka    schedule 28.11.2010

Идентификаторы - это токены, поэтому по тому же правилу последовательности токенов программа нарушает ODR.

person lijie    schedule 28.11.2010