我正在尝试编译一个非常简单的c ++代码,并根据gcc参数的顺序获得链接错误。有人能解释这两个命令行之间的区别吗?
//这很好用
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是否关心参数序列?
示例:
//此案例工作精细
[karen@linux40 ~/C++]$ ls Employee.cpp Employee.h Main.cpp [karen@linux40 ~/C++]$ gcc -x c++ -c *.h *.cpp [karen@linux40 ~/C++]$ ls Employee.cpp Employee.h Employee.o Main.cpp Main.o Makefile [karen@linux40 ~/C++]$ gcc -lstdc++ *.o -o exe [karen@linux40 ~/C++]$ ls exe Employee.cpp Employee.h Employee.o Main.cpp Main.o
//这就是问题案例
[karen@linux40 ~/C++]$ ls Employee.cpp Employee.h Main.cpp [karen@linux40 ~/C++]$ gcc -x c++ -c *.cpp *.h [karen@linux40 ~/C++]$ ls Employee.cpp Employee.h Employee.o Main.cpp Main.o [karen@linux40 ~/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;
}
答案 0 :(得分:1)
我认为提问者在非标准位置使用标头,因此将它们显式传递给编译器。如果* .c中的代码需要* .h才能工作,那么在代码之后传入头文件会产生错误,而相反的顺序却没有。
如果您使用
添加标题#include <file.h>
编译器将无法在当前目录中找到它们(除非您将代码保存在/ usr / include ...中),因此请使用
#include "file.h"
代替与代码位于同一目录中的标头。如果他们在其他地方,请添加
-I /path/to/headers/
到gcc命令。
祝你好运!答案 1 :(得分:0)
通常,您不应将.h文件直接传递给编译器。这没有任何意义,也不正确。
但看起来这里的问题主要是为了理解gcc是如何工作的。所以我的答案是从这个角度出发的。
我假设您在.cpp文件中包含相同的.h文件。
首先传递.cpp然后传递.hpp会发生什么,编译器会看到声明,然后是定义,然后是声明。这会导致链接器错误,因为第二个声明没有相应的定义。
相比之下,如果先传递.h,然后传递.cpp,它会看到两个声明,然后是定义,链接正常。