I'm trying to compile a very simple c++ code and get a linking error depending on sequence of gcc parameters. Could anybody explains what is the difference between these two command line rows?
// This works fine
gcc -x c++ -c *.h *.cpp (first I pass *.h files then *.cpp)
gcc -lstdc++ *.o -o exe
// This gives an error
gcc -x c++ -c *.cpp *.h (first I pass *.cpp files then *.h)
gcc -lstdc++ *.o -o exe
Does gcc care of the parameters sequence?
Examples:
// THIS CASE WORKS FINE
[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
// THIS IS THE PROBLEMATIC CASE
[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;
}
Generally you should not pass .h file directly to compiler. That does not make any sense and is not correct.
But looks like the question here is mainly for understanding how gcc works. So my answer is from this perspective.
I assume you include the same .h file in .cpp file.
What happens when you pass the .cpp first then .h, the compiler sees a declaration, then definition and then again a declaration. This causes a linker error, as there is no corresponding definition for the second declaration.
In contrast if you pass the .h first then .cpp, it sees two declarations and then the definition, which links fine.