Здравствуйте, Аноним, Вы писали: А> хочется понять почему генерируется код не для локальной структуры, а для объявленной в другом *.cpp файле.
В языке C++ есть One Definition Rule (ODR).
Своим кодом ты его нарушил. Это и приводит к наблюдаемым эффектам.
Две структуры с одинаковым именем в двух cpp
От:
Аноним
Дата:
12.04.14 16:07
Оценка:
Сейчас компилирую код. Есть несколько файлов, в одном их них определена структура
в другой форме. Этот файл не использует h файл в котором объявлен первый вариант.
Я использую структуру так
CDirItem di;
При выполнении программа падает. Под отладкой вижу, что вызывается конструктор первой структуры, т.е не той что нужно. Ситуация исправляется сменой имени CDirItem на CDirItem2 в основном файле, но хочется понять почему генерируется код не для локальной структуры, а для объявленной в другом *.cpp файле. Я сделал небольшой тестовый проект с аналогичной ситуацией и на нем компилятор использует структуру, объявленную в том же самом *.cpp файле, а не в другом...
Здравствуйте, Аноним, Вы писали:
А>Сейчас компилирую код. Есть несколько файлов, в одном их них определена структура
А тот хедер случайно в прекомпайлед хедер не попадает?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Я автор вопроса, почему-то не могу больше под анонимом писать в тему. Почитал про ODR, попробовал разные варианты компиляции. У меня получается следующая картина — линкер выдает ошибки в соответствии этому правилу только для двойных определений переменных и функции. А как же определения классов и структур? Если это так опасно, почему нет для этого диагностики?
Re[3]: Две структуры с одинаковым именем в двух cpp
Здравствуйте, greydrone, Вы писали:
G>Почитал про ODR, попробовал разные варианты компиляции. У меня получается следующая картина — линкер выдает ошибки в соответствии этому правилу только для двойных определений переменных и функции. А как же определения классов и структур? Если это так опасно, почему нет для этого диагностики?
Так исторически сложилось, что в языках C и С++ нет модулей или аналогичного механизма. Вместо этого есть более-менее работающая раздельная компиляция, результаты которой собираются отдельной программой — linker. Вот и получается, что компилятор не может проверить ODR, так как не имеет доступа к другим единицам трансляции, а линкер не может проверить ODR так как не видит исходного кода (да и вообще, не умеет читать исходный код на C++).
Это, конечно, не означает, что проверку сделать совсем уж невозможно. Лишь означает, что её в общем случае сделать настолько трудно, что даже в стандарте написали о её необязательности. В каких-то частных случаях, вроде двух одинаковых переменных, у линкера действительно просто получится найти ошибку.
Так для борьбы с нарушениями ODR можно использовать соответствующие анализаторы кода, которые умеют обрабатывать сразу всю программу целиком. Ну и вообще, полезно соблюдать в данной области гигиену в коде — различные блоки писать в различных пространствах имён — это хорошо помогает от дублирования банальных имён.
Re[3]: Две структуры с одинаковым именем в двух cpp
Здравствуйте, greydrone, Вы писали:
G>Я автор вопроса, почему-то не могу больше под анонимом писать в тему. Почитал про ODR, попробовал разные варианты компиляции. У меня получается следующая картина — линкер выдает ошибки в соответствии этому правилу только для двойных определений переменных и функции. А как же определения классов и структур? Если это так опасно, почему нет для этого диагностики?
Вероятно, конструктор объявлен инлайном в описании структуры, но фактически не инлайнится?
С инлайновыми функциями, которые фактически становятся не инлайновыми, есть та сложность, что в программе может оказаться много их экземпляров, и линкер должен выбрать какой-то один, а остальные выкинуть. Просто ругаться на дублирующийся символ он в этом случае не может. А надежных механизмов проверки того, что все экземпляры одной и той же функции не конфликтуют, к сожалению, не предусмотренно.
Re[4]: Две структуры с одинаковым именем в двух cpp