Vincent
Vincent

Reputation: 1734

Inlining methods : drawbacks

I have a question concerning inlining methods. I am using a library developed for collision models. One header file responsible for graphic interface contains declaration and implementation of the functions but the functions are not inlined. Therefore, it is impossible to include those functions in several translation units. As an illustration here is a dummy code I designed for illustration :

LivingBeing.h

#ifndef LIVINGBEING_H
#define LIVINGBEING_H

class LivingBeing
{
public:
    LivingBeing(double _size);
    void breathe();
private:
    double size;
};
//////////////

LivingBeing::LivingBeing(double _size)
{
    size = _size;
}
void LivingBeing::breathe()
{
    // do something
}
#endif

Forest.h

#ifndef FOREST_H
#define FOREST_H

#include "LivingBeing.h"

class Forest
{
public:
    Forest(int _numberLivingBeings);
private:
    int numberLivingBeings;
};

#endif

Forest.cpp

#include "Forest.h"

Forest::Forest(int _numberLivingBeings)
{
    numberLivingBeings = _numberLivingBeings;
            // Call LivingBeing constructor, methods etc...
}

Main.cpp

#include "Forest.h"

int main()
{
    Forest forest = Forest(10);
    return 0;
}

This code does not compile unless I add the inline keyword in front of the constructor LivingBeing and the method breathe. The error message is :

1>main_test.obj : error LNK2005: "public: __thiscall LivingBeing::LivingBeing(double)" (??0LivingBeing@@QAE@N@Z) already defined in Forest.obj
1>main_test.obj : error LNK2005: "public: void __thiscall LivingBeing::breathe(void)" (?breathe@LivingBeing@@QAEXXZ) already defined in Forest.obj
1>C:\Users\******\Documents\Visual Studio 2010\Projects\TutorialChronoEngine\Debug\Test_3.exe : fatal error LNK1169: one or more multiply defined symbols found

My question is : what is the drawbacks of inlining methods ? The real library I am using is pretty large, I would like to inline methods from a specific file (in my example it would be LivingBeing.h) so that it is possible to use those methods in several .cpp files. What am I risking by changing the source file as such ?

Thanks a lot

Upvotes: 1

Views: 182

Answers (2)

mark
mark

Reputation: 5469

Just because a method is defined in a "source" file (.c/.cpp) doesn't mean it won't be inlined... link-time operations may perform that optimization. Oppositely, just because a method is declared and implemented as inline in a header file doesn't mean it will be inlined. In general, I define methods in a header file if they are very simple, e.g. int getWidth() const { return width; }, or MyObj* getNext() { return internal_itor ? internal_itor->next : 0; }

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254501

You are defining functions (LivingBeing::LivingBeing and LivingBeing::breathe) in a header, which means there will be a definition in each translation unit that includes that header. This breaks the One Definition Rule (ODR), hence the link error.

You have three options:

  • Move the function definitions into a source file so they are only defined once; or
  • Declare them inline to allow multiple identical definitions; or
  • Move the definitions inside the class definition, which implicitly makes them inline.

what is the drawbacks of inlining methods ?

  • Possibly increased compilation time and executable size; but you'd need to measure to see whether there's any noticable difference.
  • A less stable API - client code will need recompiling whenever any inline function changes.
  • The possibility of accidentally breaking the ODR, for example if a function contains macros which might have different expansions in different translation units.

Upvotes: 4

Related Questions