Я работаю над упражнениями из Принципов и практики программирования с использованием Visual Studio 2012. При попытке скомпилировать приведенный ниже исходный код я получаю ошибку компоновщика:
неразрешенный символ int foo.
Я не понимаю, почему символ не разрешен.
extern int foo;
void print_foo();
void print(int);
#include "my.h"#include "../../std_lib_facilities.h"
void print_foo()
{
cout<<foo<<'\n';
}
void print(int i)
{
cout<<i<<'\n';
}
#include "my.h"
int main(){
int foo = 7;
print_foo();
print(99);
}
extern int foo;
Это декларация. Он говорит компилятору «там будет переменная с именем foo
типа int
в глобальном пространстве имен, определенном где-то «.
int main(){
int foo = 7;
// ...
}
Это определяет локальную переменную foo
типа int
внутри функции main()
и инициализирует его до 7. Эта локальная переменная не видна за пределами main()
,
То, что вы не сделали, это на самом деле определять foo
в глобальном пространстве имен. Для этого добавьте эту строку в точно один либо my.cpp
или же use.cpp
после включает в себя:
int foo;
Это определяет переменную с именем foo
типа int
в глобальном пространстве имен. (Как объект статической длительности хранения, foo
по умолчанию инициализируется в ноль, хотя вы также можете предоставить другой инициализатор, если хотите.) Затем компоновщик сможет разрешить ссылку на глобальный foo
это в print_foo()
когда вы связываете объектные файлы вместе.
Очень важно, чтобы вы только определять foo
один раз, хотя вы можете объявлять это столько раз, сколько вы хотите. В противном случае нарушается Правило единого определения, что приводит к ошибке компоновщика, если вам повезет, и неопределенному поведению, если это не так.
Это утверждение
extern int foo;
это объявление имени foo. Это не определение фу.
Вы должны инициализировать эту переменную, чтобы она была определением. Например
extern int foo = 0;
Хотя я не вижу смысла в вашем коде.
Может быть, вы имели в виду следующее. Я предполагаю, что переменная определена в модуле, потому что я не вижу смысла использовать заголовок, если есть только один модуль.
/* my.cpp */
#include "../../std_lib_facilities.h"
extern int foo = 0;
void print_foo();
void print(int);
void print_foo()
{
cout<<foo<<'\n';
}
void print(int i)
{
cout<<i<<'\n';
}
int main(){
extern int foo;
foo = 7;
//...
Если вы хотите использовать заголовок, то код может выглядеть как
/* my.h */
extern int foo;
void print_foo();
void print(int);
/* my.cpp */
#include "my.h"#include "../../std_lib_facilities.h"
int foo;
void print_foo()
{
cout<<foo<<'\n';
}
void print(int i)
{
cout<<i<<'\n';
}
/* use.cpp */
#include "my.h"
int main(){
extern int foo;
foo = 7;
print_foo();
print(99);
}