2012-12-30 149 views
2

我有三個文件:myh.h; my.cpp; use.cpp。以下是文件的內容:C++:鏈接文件與GCC編譯器

myh.h

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

my.cpp

#include "myh.h" 
#include <iostream> 
void print_foo() 
{ 
    std::cout<<foo<<std::endl; 
} 
void print(int i) 
{ 
    std::cout<<i<<std::endl; 
} 

use.cpp

#include "myh.h" 
int main() 
{ 
    foo=7; 
    print_foo(); 
    print(99); 
    return 0; 
} 

GCC發出以下錯誤:

my.o:my.cpp:(.text+0x7): undefined reference to `foo' 
use.o:use.cpp:(.text+0x10): undefined reference to `foo' 
collect2: ld returned 1 exit status 

我使用-c命令編譯文件,它不會給出錯誤。我鏈接使用以下命令:

g++ -o final my.o use.o 

有什麼問題就在這裏,我看到其他主題類似的問題,這裏的情況纔怪.....

對於好奇這是一個使用C++

編輯的Stroustrup的書編程原則練習鑽:我一樣dasblinkenlight說,在use.cpp我FOO的前面加一個int(所以現在foo的定義),但我仍然得到這個錯誤:

my.o:my.cpp:(.text+0x7): undefined reference to `foo' 
collect2: ld returned 1 exit status 

它告訴我,它也沒有在my.cpp中定義?如果我不得不在任何地方將它定義在頭文件中,或者應該如何更恰當地處理它?

+0

@mcalex也無所謂什麼名字,只要是同 – lekroif

+0

@lekroif:其實,如果你需要與Sun CC的鏈接並使用其有趣的外部模板機制,如果在頭中聲明瞭一個模板,那麼您顯然希望爲頭和實現擁有不同的基名(否則只要使用該模板就會包含實現文件) 。 –

+0

@Dietmar我懷疑有些編譯器可能會這樣做,這就是爲什麼我將頭文件命名爲myh.h的原因。在原始練習中,說明將其命名爲my.h(與cpp文件相同)。 – lekroif

回答

8

你得到一個鏈接錯誤,因爲你宣佈foo,但你永遠不定義它。

extern int foo只是一個聲明;它不會導致爲foo變量分配內存,只承諾您將在其他某個位置執行此操作。爲了解決這個問題,就需要加入這一行的cpp文件之一,是這樣的:

#include "myh.h" 
int foo; 
int main() 
{ 
    foo=7; 
    print_foo(); 
    print(99); 
    return 0; 
} 
+0

好吧,邏輯上,我在use.cpp中通過在其前面添加「int」來定義foo。我收到一個錯誤,但我仍然有鏈接錯誤: my.o:my.cpp :(。文本+ 0x7):未定義引用'foo' collect2:ld返回1退出狀態 爲什麼?如果我在每個文件中定義它,那麼包含它的意義是什麼...... – lekroif

+0

@lekroif我編輯了答案以顯示何處定義'foo'(它需要位於全局範圍內,即最外面的範圍)。我在本地嘗試,並且一切正常。 – dasblinkenlight

+0

是的,謝謝!!!我會做更多的閱讀來弄清楚我的困惑的來源。 – lekroif

3

的問題是,foo聲明,但沒有定義。你需要在翻譯單位只有一個定義foo,如:

int foo = 0;