Nilesh
Nilesh

Reputation: 624

G++ won't accept inline constructors in C++

I have a problem, may be dumb.

The thing is, I am unable to inline a constructor in a class.

Consider I have a class called Foo.

If I write the implementation of Foo something like this:

class Foo {
  int p;
  public:
    Foo() { p = 1; }
};

or even like this:

class Foo {
  int p;
  public:
    Foo();
};

inline Foo::Foo() {
  p = 1;
}

The program won't compile.

I use the class using the standard method:

Foo obj;

Now when I run g++ main.cpp foo.cpp, I get:

/tmp/ccyVtxvp.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `Foo::Foo()'
collect2: ld returned 1 exit status

At the same time, when I use the same code, after compiling the class as a shared library (with factory functions to return object pointer), it works properly.

Any guesses why this is happening?

Upvotes: 2

Views: 2110

Answers (7)

JP19
JP19

Reputation:

I) When directly building the object, the compiler tries to minimize the work and the object size. Here are the steps the compiler takes:

1) Compile main.cpp. Encounters a call to Foo. At this time, compiler JUST checks the declaration of Foo. The declaration is not inline, hence it adds a function call to Foo in the code.

2) Compiles file.cpp (file containing your class definition). Note that inline functions are NOT compiled (rightly so). They are just expanded to code wherever the function is called (provided the definition is available in that file).

3) Now, when it tries to link, it does not find the definition of Foo.

II) When building as a library, compiler will compile all associated functions. (you can very well guess why). Hence the linking goes through.


I am sure you know how to solve the problem yourself:

class Foo {
  int p;
  public:
    inline Foo() { p = 1; };
};

but assume you were just wondering why the different behaviour in direct object creation vs building a library.

Upvotes: 0

Baltasarq
Baltasarq

Reputation: 12212

The problem is this one:

/tmp/ccyVtxvp.o: In function main': main.cpp:(.text+0x17): undefined reference toFoo::Foo()' collect2: ld returned 1 exit status

I infer that you have the class defined in foo.cpp, and you're trying to use it in main.cpp. As others have said, C++ don't know how to use Foo, or even its existence, if you don't declare it previously. Module management in C++ is quite complex, and primitive. You're maybe biased by other more modern programming languages such as C# or Java.

Create foo.h:

// foo.h
class Foo:
int p;
public:
    Foo() { p = 1; }
};

All the methods you define in the class declaration are automatically considered inline. As a dumb rule, you should create a .cpp file (foo.cpp) matching each declaration or interface file (foo.h). In this case, it is fruitless, since your complete class lies in the interface file. Bur probably your class will grow in complexity, and eventually you'll need to have a method definition in your cpp. So:

Create foo.cpp:

// foo.cpp
#include "foo.h"

Now, in main.cpp you can use Foo, by including its declaration. This is mandatory in C++:

Create main.cpp:

// main.cpp

#include "foo.h"

#include <cstdlib>
#include <cstdio>

int main()
{
    Foo f;
    std::printf( "Foo was created\n" );

    return EXIT_SUCCESS;
}

Upvotes: 0

Kiril Kirov
Kiril Kirov

Reputation: 38173

Here

inline Foo::Foo() {
     p = 1;
}

remove the inline. Add it in the declaration (in the header)

I'm not sure why this works, but works. I've had the same problem and this solved it.


EDIT: something like this:


class Foo {
  int p;
  public:
  //vvvvvv
    inline Foo();
};

Foo::Foo() {
  p = 1;
}

Upvotes: 0

Mike DeSimone
Mike DeSimone

Reputation: 42805

My guess is that something is taking the address of Foo::Foo(). This will cause the compiler to expect a non-inlined version to exist somewhere.

Upvotes: 0

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133024

Inline functions must be defined in every source file in which they are used. The easiest way to achieve this is to put the definition(body) of the function in the header file and include the header wherever the function is used

Upvotes: 5

Alex Brown
Alex Brown

Reputation: 42892

You haven't mentioned what's in the header file and what's in the cpp.

To me this looks like you haven't actually compiled Foo::Foo. This can happen when you use inlines.

Upvotes: 0

BЈовић
BЈовић

Reputation: 64223

Your program compiles, but doesn't link. Most likely you didn't include the object file containing the definition for the Foo class.

Or, if you defined it in a header, you just forward declared it, but didn't include the header.

Upvotes: 1

Related Questions