Я делаю пример упражнений в учебнике, который я использую для изучения. Все, что мне нужно сделать, это собрать, ссылку и выполните следующие 3 файла:g ++ не удается связать файлы .o в исполняемом файле
//file my.h
extern int foo;
void print_foo();
void print(int);
my.h простого заголовочный файл, который объявляет две функции и «глобальный» Int Foo, без начального значения.
//file my.cpp
#include "my.h"
#include "std_lib_facilities.h" //not included but not source of error
void print_foo()
{
cout << foo << endl;
}
void print(int i)
{
cout << i << endl;
}
my.cpp содержит реализацию функций, включенных в my.h. std_lib_facilities.h - это файл из учебника и не является источником ошибки (согласно g ++). Я могу отредактировать его в теле вопроса, если это необходимо.
//file use.cpp
#include "my.h"
#include <iostream>
int main() {
foo = 7;
print_foo();
print(99)
char cc; cin >> cc;
return 0;
}
use.cpp служит в качестве основного файла реализации в этой программе, и пытается использовать все три объявленных & определенные объекты.
Я использовал двухступенчатый командный подход для построения с использованием g ++. Во-первых, я скомпилированные как .cpp файлы:
g++ -c my.cpp use.cpp
, которые создали два объектных файлов, my.o и use.o. Я использовал следующую команду, чтобы связать их:
g++ -o myprog my.o use.o
дает мне эту ошибку:
Undefined symbols for architecture x86_64:
"_foo", referenced from:
print_foo() in my.o
_main in use.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)
Я попытался положить
int foo;
в my.h вместо
extern int foo;
, который дал мне ту же ошибку.
Я попытался использовать флаг
-std=c++11
, а в результате которого в одной и той же ошибки.
Я использую MacBook Pro с последним macOS (только что обновленным на самом деле), если это помогает с интерпретацией сообщения об ошибке.
Я попытался инициализировать foo, который ничего не изменил.
Кроме того, я пробовал обновлять инструменты командной строки, такую же ошибку.
Насколько я понимаю, ошибка говорит мне, что хотя my.h включен в оба файла, ни один из них не может реально реализовать какую-либо функцию, используя переменную foo (которую он вызывает _foo), несмотря на то, что она явно объявлена в my.h. Я предполагаю, что компоновщик использует неправильные имена под капотом, что делает невозможным ссылку на исполняемый файл. Это связано с тем, что указанная погрешность была отмечена как
__Z9print_foov
, который нигде не существует ни в одном из файлов.
Это почти похоже на ошибку g ++ или macOS/Command Line в этой точке. Я не хочу добавлять объявления каждый раз, потому что это все равно создает дубликаты символов. Поместите my.cpp и используйте.cpp в один файл, вероятно, будет правильно связываться, но мне нужно убедиться, что я могу связать несколько файлов cpp, потому что в конечном итоге (надеюсь) будет работать с несколькими файлами cpp, которые необходимо связать. Любая помощь приветствуется!
Объявлено int foo; в my.cpp; это сработало! Спасибо за помощь. Я не понимаю, почему у компоновщика были проблемы, однако, если переменная была объявлена в заголовке и, следовательно, в .cpp-файле, который включает его (если только я что-то не хватает). Какой смысл объявлять extern int foo в заголовке, если мне все равно придется объявить его снова в файле .cpp? Ради соглашения? Я не думаю, что extern делает что-то особенное, но все еще любопытно, так что у меня опять нет этой проблемы. – gasoline
Подробнее о вашей книге на C++ о разнице между объявлением переменной и ее определением. –
Достаточно честный. Комментарий к ошибке был больше разочарован, чем что-либо еще, не намеревался подорвать усилия, которые пошли в gcc haha. Будем стараться быть более смиренными. Спасибо, что нашли время, чтобы дать мне совет, а не только ответить на вопрос! Я прочитал некоторую документацию и понял, что простой int foo, даже без какого-либо инициализированного значения, считается объявлением И определением, в то время как extern int foo в заголовке объявлялся без определения и, следовательно, оставался неопределенным, вызывая мою ошибку. – gasoline