2012-03-21 120 views
-1

我想編譯一個非常簡單的C++代碼,並根據gcc參數的順序獲取鏈接錯誤。任何人都可以解釋這兩個命令行之間有什麼區別嗎?使用「gcc」編譯器編譯C++簡單文件

//這工作得很好

gcc -x c++ -c *.h *.cpp (first I pass *.h files then *.cpp) 
gcc -lstdc++ *.o -o exe 

//這給出了一個錯誤

gcc -x c++ -c *.cpp *.h (first I pass *.cpp files then *.h) 
gcc -lstdc++ *.o -o exe 

請問GCC護理參數序列?

實例:

//這CASE工作正常

 

    [[email protected] ~/C++]$ ls 
    Employee.cpp Employee.h Main.cpp 
    [[email protected] ~/C++]$ gcc -x c++ -c *.h *.cpp 
    [[email protected] ~/C++]$ ls 
    Employee.cpp Employee.h Employee.o Main.cpp Main.o Makefile 
    [[email protected] ~/C++]$ gcc -lstdc++ *.o -o exe 
    [[email protected] ~/C++]$ ls 
    exe Employee.cpp Employee.h Employee.o Main.cpp Main.o 

//這是有問題的CASE

 

    [[email protected] ~/C++]$ ls 
    Employee.cpp Employee.h Main.cpp 
    [[email protected] ~/C++]$ gcc -x c++ -c *.cpp *.h 
    [[email protected] ~/C++]$ ls 
    Employee.cpp Employee.h Employee.o Main.cpp Main.o 
    [[email protected] ~/C++]$ gcc -lstdc++ *.o -o exe 
    Main.o: In function `main': 
    Main.cpp:(.text+0x8d): undefined reference to `Employee::Employee()' 
    collect2: ld returned 1 exit status 

Employee.h

#include <iostream> 
#include <string> 
using namespace std; 

class Employee { 
public: 
    Employee(); 
    Employee(string theName, float thePayRate); 

    string getName() const; 
    float getPayRate() const; 

    float pay(float hoursWorked) const; 

protected: 
    string name; 
    float payRate; 
}; 

Employee.cpp

#include "Employee.h" 

Employee::Employee() { 
} 

Employee::Employee(string theName, float thePayRate) { 
    name = theName; 
    payRate = thePayRate; 
} 

string Employee::getName() const { 
    return name; 
} 

float Employee::getPayRate() const { 
    return payRate; 
} 

float Employee::pay(float hoursWorked) const { 
    return hoursWorked * payRate; 
} 

Main.cpp的

#include "Employee.h" 

int main() { 
    Employee e; 
    return 0; 
} 
+14

您不應該將.h文件傳遞給gcc。 – 2012-03-21 00:21:56

+2

什麼是'錯誤'?另外,你的'* .h'文件中有什麼必須明確地將它們提供給編譯器? – 2012-03-21 00:23:38

+0

是的,它確實關心鏈接庫的順序,儘管這完全與你的錯誤無關,但與你的問題有關 – learnvst 2012-03-21 00:24:24

回答

0

通常,您不應將.h文件直接傳遞給編譯器。這沒有任何意義,也是不正確的。

但看起來這裏的問題主要是爲了解gcc如何工作。所以我的回答是從這個角度來看的。

我假設你在.cpp文件中包含相同的.h文件。

當你先通過.cpp然後.h,編譯器看到一個聲明,然後再定義,然後又一次聲明,會發生什麼。這會導致鏈接器錯誤,因爲第二個聲明沒有相應的定義。

相反,如果您先通過.h,然後。CPP,它看到兩個聲明,然後是定義,鏈接很好。

+1

@CollinHockey這是一個蹩腳的評論,太糟糕了,我們不能downvote評論。我認爲grigy很禮貌......(+ 1)糾正這一點。 – 2012-03-21 01:40:58

+1

很合理的解釋... 謝謝, 凱倫 – 2012-03-21 17:49:57

1

我假定提問是在非標準位置使用標頭,因此將它們明確地給編譯器。如果* .c中的代碼需要* .h才能工作,那麼在代碼之後傳遞標題將會導致錯誤,而相反的順序則不會。

如果你包括

#include <file.h> 

頭在當前目錄下的編譯器不會發現他們(除非你把你的代碼在/ usr/include中...),所以使用

#include "file.h" 

而是代替與代碼位於同一目錄中的標頭。如果它們位於其他地方,則向gcc命令添加

-I /path/to/headers/ 

祝你好運!

+1

請看我附上的代碼。其實我用「」而不是「> 謝謝 Karen – 2012-03-21 17:42:39

+1

所以,你是否在你的代碼相同的目錄中的標題?如果是這樣,完全停止'* .h'應該可以正常工作。 – jimw 2012-03-21 21:08:57

+0

是的,確切!他們在同一個目錄中。我已經更新了問題描述,並且您可以看到shell命令「ls」的結果,它顯示我在同一個目錄中有三個文件。 感謝您對我感興趣並試圖幫助我。 – 2012-03-22 00:38:58