使用“gcc”编译器编译C++简单文件
我想编译一个非常简单的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;
}
通常,您不应将.h文件直接传递给编译器。这没有任何意义,也是不正确的。
但看起来这里的问题主要是为了解gcc如何工作。所以我的回答是从这个角度来看的。
我假设你在.cpp文件中包含相同的.h文件。
当你先通过.cpp然后.h,编译器看到一个声明,然后再定义,然后又一次声明,会发生什么。这会导致链接器错误,因为第二个声明没有相应的定义。
相反,如果您先通过.h,然后。CPP,它看到两个声明,然后是定义,链接很好。
@CollinHockey这是一个蹩脚的评论,太糟糕了,我们不能downvote评论。我认为grigy很礼貌......(+ 1)纠正这一点。 – 2012-03-21 01:40:58
很合理的解释... 谢谢, 凯伦 – 2012-03-21 17:49:57
我假定提问是在非标准位置使用标头,因此将它们明确地给编译器。如果* .c中的代码需要* .h才能工作,那么在代码之后传递标题将会导致错误,而相反的顺序则不会。
如果你包括
#include <file.h>
头在当前目录下的编译器不会发现他们(除非你把你的代码在/ usr/include中...),所以使用
#include "file.h"
而是代替与代码位于同一目录中的标头。如果它们位于其他地方,则向gcc命令添加
-I /path/to/headers/
。
祝你好运!
请看我附上的代码。其实我用“”而不是“> 谢谢 Karen – 2012-03-21 17:42:39
所以,你是否在你的代码相同的目录中的标题?如果是这样,完全停止'* .h'应该可以正常工作。 – jimw 2012-03-21 21:08:57
是的,确切!他们在同一个目录中。我已经更新了问题描述,并且您可以看到shell命令“ls”的结果,它显示我在同一个目录中有三个文件。 感谢您对我感兴趣并试图帮助我。 – 2012-03-22 00:38:58
您不应该将.h文件传递给gcc。 – 2012-03-21 00:21:56
什么是'错误'?另外,你的'* .h'文件中有什么必须明确地将它们提供给编译器? – 2012-03-21 00:23:38
是的,它确实关心链接库的顺序,尽管这完全与你的错误无关,但与你的问题有关 – learnvst 2012-03-21 00:24:24