2012-08-05 133 views
3

我有以下3個文件:...未定義的參考... collect2:LD返回1退出狀態

error.h

#ifndef error_h 
#define error_h 
#include <string> 
#include <iostream> 
#include <cstdio> 
void Error(std::string msg); 
#endif 

error.cpp

#ifdef error_h 
#include "error.h" 
void Error(std::string msg) 
{ 
    std::cerr 
    << "\n=========================================================\n" 
    << msg 
    << "\n=========================================================\n"; 
    exit(EXIT_FAILURE); 
} 
#endif 

foob​​ar.cpp

#include "error.h" 
int main() 
{ 
    for(int i=0; i<99; i++) 
     if(i==55) 
      Error("this works"); 
    return 0; 
} 

現在我做:

$ g++ -c error.cpp foobar.cpp 
$ g++ error.o foobar.o -o exampleprogram 

我也得到:

foobar.o: In function `main': 
foobar.cpp:(.text+0x4b): undefined reference to `Error(std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >)' 
collect2: ld returned 1 exit status 

我在做什麼錯?我需要了解什麼才能解決此問題,以及未來在未提問的情況下的類似問題?謝謝!

+0

現在我也意識到exit(int)是在cstdlib中而不是在cstdio中 – user1358 2012-08-05 18:20:04

回答

3

爲什麼你有這些行error.cpp

#ifdef error_h 
    ... 
#endif 

由於預處理符號error_h沒有定義error.cpp的全部內容被由預處理器刪去。刪除這些行,您的程序將成功鏈接。

你似乎有一個誤解,如何(也可能是爲什麼)#include警衛將被使用。有關解釋,請參閱this答案。

而且,沒有必要在error.h的iostreamcstdio,因爲該文件沒有使用在任何這些頭的宣佈任何事情。這些文件應該包含在error.cpp中。

+0

謝謝!最近我一直在做很多包含模板實現的「.cpp」,我只是在沒有思考的情況下輸入這些內容,並且一直忽略它們。你提到iostream和cstdio包含...這是否意味着我必須散佈一些包含?一些在.h和一些在.cpp中?函數原型需要#include 嗎?一般來說,是不是有捆綁所有包含.h和.cpp的方法?再次感謝。 – user1358 2012-08-05 18:10:15

+1

@ user1358最好的做法是隻包含該文件中實際需要的頭文件,所以是的,包含文件往往散佈在四周。在* error.h *中包含頭文件沒有任何不正確的地方,但是當在* main.cpp *文件中包含* error.h *時,預處理器將把文件包含在* main.cpp *創建的翻譯單元中,編譯器也必須處理這些頭文件。在小型項目中並不是真正的問題,但對於大型項目來說,這會顯着影響構建時間。 – Praetorian 2012-08-05 18:16:25

+0

你的解釋幫助了很多。非常感謝你。 – user1358 2012-08-05 18:24:46

2

移除此

#ifdef error_h 

和從error.cpp相應#endif。否則,在這裏:

$ G ++ -c error.cpp foobar.cpp

error.cpp基本上是空的。這是因爲在那個階段error_h沒有定義。所以你沒有編譯實現(如果你在#ifdef之前包含了error.h,但是無論如何沒有理由在.cpp文件中有)。

+0

很好的答案謝謝 – user1358 2012-08-05 18:15:16

2

error_h未在error.cpp中定義,因此您的所有文件內容都會被#ifdef去掉。

本質上,你正在編譯error.cpp作爲一個空文件。

+0

好的答案謝謝 – user1358 2012-08-05 18:12:14