2013-02-15 2 views
22

Мой проект состоит только из двух исходных файлов:Почему «extern const int n;» не работает, как ожидалось?

a.cpp:

const int n = 8; 

b.cpp:

extern const int n; 

int main() 
{ 
    // error LNK2001: unresolved external symbol "int const n" ([email protected]@3HB) 
    int m = n; 
} 

Я знаю, что есть несколько способов, чтобы сделать его работу; однако, мне просто интересно, почему это не работает?

+7

Попробуйте изменить 'a.cpp' на' extern const int n = 8; 'AFAIK' const' подразумевает 'static', хотя я действительно не знаю. – Pubby

+0

Требуется ли a.cpp для объявления n с ключевым словом extern? – 2013-02-15 12:28:43

+0

Вы не сказали нам, что вы связываете и как ... – PlasmaHH

ответ

39

Это потому, что const подразумевает внутреннюю привязку по умолчанию, поэтому ваше «определение» не видно за пределами единицы перевода , где он отображается.

В этом случае, безусловно, лучшим решением будет поставить декларацию (extern int const n;) в файле заголовка, и включают в себя, что в как a.cpp и b.cpp. Связь определяется первым объявлением компилятора , поэтому более позднее определение в a.cpp будет иметь правильную (внешнюю) связь.

В качестве альтернативы, вы можете заставить связь в определении:

extern int const n = 8; 

Несмотря на extern, это еще определение; все с инициализатором вне определения класса является определением.

2

Объявить его ехЬегп в a.cpp и просто использовать без экстерном в b.cpp:

ах

extern const int n ; 

a.cpp

#include "a.h" 
... 
const int n= 8 

b.cpp:

#include "a.h" 
... 


int main() 
{   
    int m = n; 
} 
+0

Хм, используется для этого с файлом заголовка. Включение заголовка с помощью extern - самый простой способ. – Gjordis

+1

Собственно, вы должны * удалить * 'const int n;' из b.cpp. Входящий заголовок нужен. – Roddy

+0

@ Roddy Правильно, модифицировано соответствующим образом. – Gjordis

5

const и constexpr переменные в C++ имеют внутреннюю связь (и, следовательно, не доступны в другом модуле компиляции), если они также не объявлены extern (либо в определении или в предыдущей декларации).

В C это не тот случай (ну C не имеет constexpr), поэтому ваш код действителен, и вы можете поставить extern на определение.

Так что, если вы хотите, чтобы написать код, который является как C и C++ (и два заявления должны, вероятно, из того же заголовка, как Джеймс указал):

// a.cpp 
extern const int n; 
const int n = 8; 

// b.cpp 
extern const int n; 

int main() 
{ 

    int m = n; 
} 

если вы не

// a.cpp 
extern const int n = 8; 

также возможно

+0

@Roddy, исправленный. Не стесняйтесь сами фиксировать такие вещи, а не комментировать. – AProgrammer

1

To share a const object among multiple files, you must define the variable as extern.

To define a single instance of a const variable, we use the keyword extern on both its definition and declaration(s): 

Из этих правил вам просто нужно добавить ключевое слово extern в свое определение. вы уже имеете его в декларации.

1

Если другие ответы здесь не сделать трюк, это может быть так, что у вас есть свои определения в разных пространствах имен ... если компиляция проходит, и вы получите ошибку undefined symbol компоновщика:

  • проверьте пространство имен неопределенного символа; это эффективное пространство имен для объявления extern const int n.
  • убедитесь, что это ваше эффективное пространство имен, в котором вы определяете определение const int n = 8.