Более кратно определенные символы

0

Я перебирал эту статью, и она рассказывает о процессе компиляции (предварительный процесс, компиляция, ссылка). Я понимаю, что включение охранников просто решает проблему предотвращения множественных включений в одной и той же единице перевода. Поэтому, если у меня есть следующий сценарий:

File : Common.h
----------------
#ifndef External_Header
#include "iostream"
#define External_Header
std::string R = "dsds";
#endif

Теперь у меня есть два файла cpp, оба из которых включают этот заголовочный файл. Я понимаю, почему я получаю ошибку компоновщика "fatal error LNK1169: one or more multiply defined symbols found". Мне интересно, почему я не получаю такую же ошибку компоновщика, когда я определяю структуру вместо строки.

Любые мысли или идеи, которые могли бы прояснить это.

     File : Common.h
     ----------------
    #ifndef External_Header
    #include "iostream"
    #define External_Header
    struct mystruct
    {
        int a;
    };
    #endif
  • 2
    «почему я не получаю ту же ошибку компоновщика, когда я определяю структуру вместо строки» - потому что во втором случае вы не объявляете какие-либо переменные, вы объявляете тип (и с заголовками только один раз) за единицу перевода). Положите myvar; после закрытия фигурного определения структуры, и у вас снова будет ошибка дублированного символа. Ошибка компоновщика, которую вы получаете в первом случае, связана с тем, что идентичные символы объявляются в нескольких единицах перевода, и компоновщик не имеет ни малейшего представления, что выбрать для глобального разрешения.
Теги:

2 ответа

2
Лучший ответ

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

struct mystruct
{
    int a;
} myTestVar;
1

Это потому, что struct не являются символами.

Стандарт C++ явно позволяет нам переопределять типы в разных единицах перевода... пока их определение не изменится.

[C++11: 3.2/1]: ни одна единица перевода не должна содержать более одного определения любой переменной, функции, типа класса, типа перечисления или шаблона.

[C++11: 3.2/3]: каждая программа должна содержать ровно одно определение каждой не-встроенной функции или переменной, которая используется в этой программе odr; не требуется диагностика. [..]

Обратите внимание, как типы упоминаются в прежнем правиле, но не в последнем. Это делается немного позже:

[C++11: 3.2/5]: может быть несколько определений типа класса [..], при условии, что каждое определение отображается в другой единицы перевода и при условии, что определения удовлетворяют следующим требованиям. Учитывая такой объект с именем D определенный более чем в одной единицы перевода, тогда

  • каждое определение D должно состоять из одной и той же последовательности токенов;
  • [..]

Программирование с перекрестными переводами было бы невозможно, если бы не это различие.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню