0

Есть три файла.

my.cpp:

#include "my.hpp"
#include <iostream>
using namespace std;

void print_foo() {
    cout << foo << endl;
}

void print(int i) {
    cout << i << endl;
}

my.hpp:

extern int foo;
void print_foo();
void print(int);

use.cpp:

#include "my.hpp"

int main() {
    foo = 7;
    print_foo();
    print(99);
}

Ввожу в терминал(MAC OS):

g++ my.hpp use.cpp my.cpp

Компилятор выдаёт:

Undefined symbols for architecture x86_64:
  "_foo", referenced from:
      _main in use-0e4909.o
      print_foo() in my-c4d67b.o
     (maybe you meant: __Z9print_foov)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

В чём проблема?

  • Вообще говоря, my.hpp в командной строке совершенно не нужен. А ошибка в том, что нет определения int foo; в одном из .cpp-файлов. – Harry Jul 25 '19 at 17:35
  • Куда тогда его девать? – Матвей Суслов Jul 25 '19 at 17:37
  • Никуда - он же у вас включается в .cpp-файлы, а не компилируется отдельно... – Harry Jul 25 '19 at 17:37
  • Foo инициализируется в use.cpp – Матвей Суслов Jul 25 '19 at 17:37
  • Инициализируется, но не определяется. Есть только объявление... – Harry Jul 25 '19 at 17:38
  • Foo = 7 - не определение? – Матвей Суслов Jul 25 '19 at 17:42
  • Нет, это использование. extern int foo; говорит примерно "где-то потом я определю эту переменную, пока просто считай, что она есть". Грубая аналогия - в том же .hpp-файле у вас есть void print(int); - вас же не удивляет, что вы где-то должны описать тело этой функции? Да, еще одним решением будет в современном C++ объявить в .hpp ее как inline int foo;. – Harry Jul 25 '19 at 18:25

1 Answers1

0

Добавь в файл my.cpp:

int foo;

Тогда зачем я его экстерном в заголовочном объявлял?

Он там означает "где-то есть такая переменная, её можно использовать". Но вот это "где-то есть" тебе ещё надо обеспечить.

Qwertiy
  • 123,725