Reputation:
C.h has
#ifndef UNTITLED3_C_H
#define UNTITLED3_C_H
class C {
public:
int F();
};
#endif //UNTITLED3_C_H
C-inl.h has
#ifndef UNTITLED3_C_INL_H
#define UNTITLED3_C_INL_H
#include "C.h"
int C::F() {
return 1;
}
#endif //UNTITLED3_C_INL_H
main.cpp has
#include <iostream>
#include "C.h"
int main() {
C c;
std::cout << c.F() << std::endl;
return 0;
}
Now I compile them with the following command, but fails.
$ g++ main.cpp C-inl.h -o main
/tmp/ccVkEs1w.o: In function `main':
main.cpp:(.text+0x1f): undefined reference to `C::F()'
collect2: error: ld returned 1 exit status
Then I rename C-inl.h to C.cpp, the compilation works.
$ g++ main.cpp C.cpp -o main
$ ./main
1
Why does file name make a difference?
When the files are main.cpp, C.h, and C.cpp
, main.cpp only includes C.h, how does the content of C.cpp kick in? When the files are main.cpp, C.h, and C-inl.h
, why doesn't the content kick in?
Upvotes: 0
Views: 88
Reputation: 30579
By default, GCC determines what to do with each file you specify by looking at its extension.
From the gcc(1):
file.h
C, C ++ , Objective-C or Objective-C ++ header file to be turned into a precompiled header.
So GCC assumes you want to use "C-inl.h" and "C.h" as precompiled headers.
You can override GCC's decision using the -x
flag:
g++ main.cpp -x c++ C-inl.h -o main
I would recommend against doing this though. C++ headers usually aren't compiled as separate compilation units, and doing so will make the next person to read you code very confused. "C-inl.h" is not a header. Name it what it really is: "C.cpp".
Upvotes: 0
Reputation: 7198
class C {
public:
int F();
};
is a declaration of function F()
as a member of class C
.
int C::F() {
return 1;
}
is the definition of that function.
If you include only C.h
you have NOT the definition needed at main()
. The compiler knows you want that 'F()' but doesn't have a reference for its definition (the "undefined reference" error message).
Now you rename C-inl.h
to C.cpp
and compile it. The trick is that C.cpp
does include the C.h
where the declaration is done. So everything is found, compiled and linked.
Hey, C-inl.h
includes C.h
and I told g++ to compile C-inl.h
!!
Yeah, but gcc docs remarks how g++ takes the .h
extension:
file.h
C, C++, Objective-C or Objective-C++ header file to be turned into a precompiled header (default)
And you need that file to be handled as a .cpp
file, not precompiled header.
Upvotes: 0