Please help with the following noob question about C++ and g++ compilation and linking. Essentially I have 2 classes in 2 different files, and can compile them but when I attempt to link, one class can’t see the methods of the other, even though I am linking both. Order of object files does not help in this case.
The problem seems related to a non-default constructor that takes a parameter.
I have distilled and reproduced the problem in the following simple code:
File: a.cpp:
#include <iostream>
class A
{
public:
int my_int;
A(int i) {
my_int = i;
std::cout << "A";
}
};
File: a.hpp:
#ifndef __A_H_
#define __A_H_
class A
{
public:
A(int i);
};
#endif
File b.cpp:
#include <iostream>
using namespace std;
#include <a.hpp>
class B
{
public:
int my_int;
B(int i) {
my_int = i;
A a(i);
cout << "B\n";
}
};
int main(int argc, char* argv[])
{
B b(5);
cout << "hello world: ";
cout.flush();
return 0;
}
Commands I use to build:
g++ -c -I. a.cpp
g++ -c -I. b.cpp
g++ -o c_test a.o b.o
Alternately, I’ve tried each of these:
g++ -o c_test b.o a.o
g++ -I. -o c_test a.cpp b.cpp
g++ -I. -o c_test b.cpp a.cpp
Error I get in any of above link scenarios:
b.o: In function `B::B(int)':
b.cpp:(.text._ZN1BC1Ei[B::B(int)]+0x1c): undefined reference to `A::A(int)'
collect2: ld returned 1 exit status
Thanks in advance for any insight.
(sorry if this is a re-post — I thought I posted it and don’t see it…)
It doesn’t work that way. What you’ve come across is technically an ODR violation, which roughly means that
Ain botha.cppandb.cppmust be the same thing. It isn’t.Moreover, the constructor is implicitly
inlinein a.cpp and therefore its code needn’t be emitted.Changing
a.cpptowill fix the error.