SLN
SLN

Reputation: 5082

Defined multiple times for the inline function, how possible?

The following quote from c++ primer book confuse me a lot

Unlike other function, inline and constexpr functions may be defined multiple times in the program. After all, the compiler needs the definition, not just the declaration, in order to expand the code. However, all of the definitions of a given inline or constexpr must match exactly. As a result, inline and constexpr functions normally are defined in headers. -- C++ primer 5th Ed, 240 pp

"may be defined multiple times in the program" This quote confuse me a lot. As far as I understand, declaration can be made multiple time, but definition is only needed once.

can someone give me an example why there is a multiple definition.

Upvotes: 6

Views: 1796

Answers (3)

Gelldur
Gelldur

Reputation: 11558

As an example. This version isn't valid.

// main.cpp
inline int square(int num) {
    return num * num;
}

inline int square(int num) {
    return num * num;
}

int main()
{
    return square(2);
}

https://godbolt.org/z/nlSbxg

But when you have it in multiple .cpp files (aka. translation units) it is ok because it is now linker job to do right thing.

// b.cpp
inline int square(int num) {
    return num * num;
}

// main.cpp
inline int square(int num) {
    return num * num;
}

int main()
{
    return square(2);
}

Build: gcc main.cpp b.cpp Same way works #include it will place code in those .cpp files that's all.

Of course if body of function is inlined, then nothing to link so no problem :)

If compiler decides to do an out-of-line version you end up with more than one object file (.o) having definition for the same "inline" function. Such definition will be marked.

Thanks to that mark linker won't yield that it has found multiple definitions and just pick first one that it finds.

So if all definitions are truly the same, then fine! We will get into troubles if we have different body of such function. Example in file b.cpp

// b.cpp
inline int square(int num) {
    return 1;
}

It is undefined behavior to have multiple different definitions of the same inline function. It will compile of course but what we get? It depends on linker choice :D

Upvotes: 4

Peter Ruderman
Peter Ruderman

Reputation: 12485

I think the problem is that there are multiple things we can mean by "define." When you write an inline function in a header file, it's "defined" just once in the sense that there is only a single function with that name in your source code.

But that's not how the compiler and linker see the world. If you have an inline function foo in a header file that's called from a.cpp and b.cpp, then the complete compiled version of that function will be included in both a.obj and b.obj. The linker resolves the issue by picking just one of those compiled versions to include in your final binary.

Note that I'm glossing over significant details here, but this is the general idea (and what I think your textbook is eluding to).

Upvotes: 2

NathanOliver
NathanOliver

Reputation: 180650

In a header file (lets call it foo.h) you can have

inline int foo() { /* do stuff */ }

Now if you include foo.h in a couple cpp files then foo will be defined in each of them, which would be a multiple definition error. Since foo is marked as inline though, it is okay because all of the definitions are the same.

As far as I understand, declaration can be made multiple time, but definition is only needed once

The compiler works on translation units (basically a cpp file) and in it, it can do all sorts of optimizations but function inlining and constexpr require that the compiler know the definition of the function. That means each translation unit needs the definition of the function in it. We use inline to make that okay, otherwise it would be a multiple definition error.

Upvotes: 3

Related Questions