tyl3rdurd3n
tyl3rdurd3n

Reputation: 71

Compilation error while including cpp file in main: Inline versus non-inline functions

I have a conceptual doubt which i'll try to put across using an example:

main.cpp

#include "array_list.cpp"
int main() 
{
  array_list list1;
  return 0;
}

Scenario1: array_list.cpp->

class array_list
{
    private:
    int list[10];
public:
    array_list () {};
    ~array_list () {};
    void set_element (int,int);

};

void array_list::set_element (int i,int a) {
list[i] = a;
}

Error:

main.obj : error LNK2005: "public: void __thiscall array_list::set_element(int,int)" (?set_element@array_list@@QAEXHH@Z) already defined in array_list.obj 1>C:\Users\vrastog\Documents\Visual Studio 2012\Projects\C++ learning\Debug\list using arrays.exe : fatal error LNK1169: one or more multiply defined symbols found

Scenario 2: array_list.cpp->

class array_list
{
private:
    int list[10];
public:
    array_list () {};
    ~array_list () {};
    void set_element (int i,int a) {
        list[i] = a;
    }
};

Error: No error!!

Question: I understand the reason for error. The same method has been defined twice, once in main.obj and second in array_list.obj and hence, it should be an error. My question is why does the second scenario work? Here also, since we have includes array_list.cpp in the main file, 'set_element' should have been defined twice here as well. What am I missing here?

Upvotes: 1

Views: 124

Answers (2)

Csq
Csq

Reputation: 5855

In-class definition makes a method inline, and therefore it does not cause a multiple definition error in the object file.


An inline method should be implemented in every translation unit it is used in, so the inline method compiles into both object files.

C++ Standard Draft (n3797) 3.2.4: An inline function shall be defined in every translation unit in which it is odr-used.

Also 3.2.6 requires that these function should be exactly the same.

g++ implements this using weak symbols: inline functions are special exported functions that do not cause multiple definition error when linking.

Use a tool like nm under Linux and see for yourself. It emits a weak symbol into the object file:

$ nm arraylist.o
00000000 W _ZN10array_list11set_elementEii
(... ctors, dtors ...)
00000000 T main

Also, if you do not use the function, or the compiler inlines all occurrences, it may get optimized out.

Upvotes: 2

Zsolt
Zsolt

Reputation: 582

Please don't include .cpp files.

In the first example, the function is defined out of class, you need to add inline, otherwise it's a multiple definition.

In the second example, the function is defined in the class definition, so it's an implicit inline function (it's like the compiler added the inline for you), that's why it's not causing multiple definitions.

Upvotes: 2

Related Questions