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

StackOverflow https://stackoverflow.com/questions/4297480

Вопрос

Я читаю и перечитаю соответствующие пункты по поводу 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;
}
Это было полезно?

Решение

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

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

Другие советы

Да, это нарушает ODR. Он использует разные последовательности токенов, я не знаю, что так сложно понять здесь.

Проверка ODR в разных единицах переводчиков жестко (невозможно) с традиционными методами компиляции. Стандарт говорит, что «никакой диагностики не требуется», поэтому вы просто получаете неопределенное поведение.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top