Re: Две структуры с одинаковым именем в двух cpp
От: watchmaker  
Дата: 12.04.14 16:46
Оценка: 2 (2) +1
Здравствуйте, Аноним, Вы писали:
А> хочется понять почему генерируется код не для локальной структуры, а для объявленной в другом *.cpp файле.
В языке C++ есть One Definition Rule (ODR).
Своим кодом ты его нарушил. Это и приводит к наблюдаемым эффектам.
Две структуры с одинаковым именем в двух cpp
От: Аноним  
Дата: 12.04.14 16:07
Оценка:
Сейчас компилирую код. Есть несколько файлов, в одном их них определена структура
struct CDirItem
{
  UInt64 Size;
  FILETIME CTime;
  FILETIME ATime;
  FILETIME MTime;
  UString Name;
  UInt32 Attrib;
  int PhyParent;
  int LogParent;
  
  CDirItem(): PhyParent(-1), LogParent(-1) {}
  bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
};

Объявление через h файл используют несколько cpp.
В основном файле тоже объявлена эта струкрута
struct CDirItem
{
  UInt64 Size1;
  UInt64 Size;
  FILETIME CTime;
  FILETIME ATime;
  FILETIME MTime;
  UString Name;
  UString FullPath;
  UInt32 Attrib;

  bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
};

в другой форме. Этот файл не использует h файл в котором объявлен первый вариант.
Я использую структуру так
CDirItem di;

При выполнении программа падает. Под отладкой вижу, что вызывается конструктор первой структуры, т.е не той что нужно. Ситуация исправляется сменой имени CDirItem на CDirItem2 в основном файле, но хочется понять почему генерируется код не для локальной структуры, а для объявленной в другом *.cpp файле. Я сделал небольшой тестовый проект с аналогичной ситуацией и на нем компилятор использует структуру, объявленную в том же самом *.cpp файле, а не в другом...
Re: Две структуры с одинаковым именем в двух cpp
От: Vain Россия google.ru
Дата: 12.04.14 16:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сейчас компилирую код. Есть несколько файлов, в одном их них определена структура

А тот хедер случайно в прекомпайлед хедер не попадает?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Две структуры с одинаковым именем в двух cpp
От: smeeld  
Дата: 12.04.14 16:35
Оценка:
Здравствуйте, Аноним, Вы писали:

Выбирая компилятор, вы выбираете судьбу. Не я придумал, автор
может тут отозваться.
Re[2]: Две структуры с одинаковым именем в двух cpp
От: greydrone Россия  
Дата: 12.04.14 17:11
Оценка:
Я автор вопроса, почему-то не могу больше под анонимом писать в тему. Почитал про ODR, попробовал разные варианты компиляции. У меня получается следующая картина — линкер выдает ошибки в соответствии этому правилу только для двойных определений переменных и функции. А как же определения классов и структур? Если это так опасно, почему нет для этого диагностики?
Re[3]: Две структуры с одинаковым именем в двух cpp
От: watchmaker  
Дата: 12.04.14 17:28
Оценка:
Здравствуйте, greydrone, Вы писали:

G>Почитал про ODR, попробовал разные варианты компиляции. У меня получается следующая картина — линкер выдает ошибки в соответствии этому правилу только для двойных определений переменных и функции. А как же определения классов и структур? Если это так опасно, почему нет для этого диагностики?

Так исторически сложилось, что в языках C и С++ нет модулей или аналогичного механизма. Вместо этого есть более-менее работающая раздельная компиляция, результаты которой собираются отдельной программой — linker. Вот и получается, что компилятор не может проверить ODR, так как не имеет доступа к другим единицам трансляции, а линкер не может проверить ODR так как не видит исходного кода (да и вообще, не умеет читать исходный код на C++).
Это, конечно, не означает, что проверку сделать совсем уж невозможно. Лишь означает, что её в общем случае сделать настолько трудно, что даже в стандарте написали о её необязательности. В каких-то частных случаях, вроде двух одинаковых переменных, у линкера действительно просто получится найти ошибку.
Так для борьбы с нарушениями ODR можно использовать соответствующие анализаторы кода, которые умеют обрабатывать сразу всю программу целиком. Ну и вообще, полезно соблюдать в данной области гигиену в коде — различные блоки писать в различных пространствах имён — это хорошо помогает от дублирования банальных имён.
Re[3]: Две структуры с одинаковым именем в двух cpp
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.04.14 17:46
Оценка:
Здравствуйте, greydrone, Вы писали:

G>Я автор вопроса, почему-то не могу больше под анонимом писать в тему. Почитал про ODR, попробовал разные варианты компиляции. У меня получается следующая картина — линкер выдает ошибки в соответствии этому правилу только для двойных определений переменных и функции. А как же определения классов и структур? Если это так опасно, почему нет для этого диагностики?


Вероятно, конструктор объявлен инлайном в описании структуры, но фактически не инлайнится?

С инлайновыми функциями, которые фактически становятся не инлайновыми, есть та сложность, что в программе может оказаться много их экземпляров, и линкер должен выбрать какой-то один, а остальные выкинуть. Просто ругаться на дублирующийся символ он в этом случае не может. А надежных механизмов проверки того, что все экземпляры одной и той же функции не конфликтуют, к сожалению, не предусмотренно.
Re[4]: Две структуры с одинаковым именем в двух cpp
От: greydrone Россия  
Дата: 13.04.14 03:15
Оценка:
Здравствуйте, Pzz, Вы писали:
...

Нет, тут все проще.

Всем спасибо, все встало на свои места.
Re[5]: Две структуры с одинаковым именем в двух cpp
От: Vain Россия google.ru
Дата: 13.04.14 19:28
Оценка:
Здравствуйте, greydrone, Вы писали:

G>Нет, тут все проще.

G>Всем спасибо, все встало на свои места.
Так в чём дело было?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.