Reputation: 1188
I'm trying to understand a few basics about extern, static, etc. and tried the following example, but I don't get why I can't call the function "just" because it's (possibly) inlined.
My first file : F1.cpp
#include <iostream>
void Modify();
int i;
int main() {
i = 1;
std::cout << "i = " << i << std::endl;
Modify();
std::cout << "i = " << i << std::endl;
return 0;
}
The second file : F2.cpp
#include <iostream>
extern int i;
inline void Modify() {
i = 99;
std::cout << "i = " << i << std::endl;
}
With inline keyword in F2.cpp, I get : undefined reference to Modify() in my F1.cpp file. Removing it, the code compiles and works fine.
I assume that the inline keyword in C++ has some sort of behaviour like the static keyword ?
I had a look at this topic aswell, but apart from the fact that the documentation says that an inline function should always be in the header file, I don't get it : C++ inline member function in .cpp file
Thanks for your help !
Upvotes: 3
Views: 2836
Reputation: 490108
Yes, inline
has a meaning that's fairly similar to static
. The specific requirement from the standard (§[basic.def.odr]/3) is:
An inline function shall be defined in every translation unit in which it is odr-used.
In this case, you've defined the inline
function in one translation unit, but only declared it in the other, so you're not meeting the requirement above that it be defined in the TU where it's used.
An inline function can still have external linkage. When you do this, the standard guarantees that it results in a single function that will have the same address throughout the program.
Just in case it wasn't clear: a translation unit is basically a source file, after preprocessing, so it includes everything directly in that source file plus everything in the headers it includes, minus anything skipped over due to things like #ifdef
, #if
, etc.
Upvotes: 2
Reputation: 310960
According to the C++ Standard (7.1.2 Function specifiers)
4....If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required.
and
4 An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case
In C ( section 6.7.4 Function specifiers of the C Standard ) function specifier inline
for external functions has different semantic
7....An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition
Upvotes: 5
Reputation: 254451
I assume that the
inline
keyword in C++ has some sort of behaviour like thestatic
keyword ?
Similar, but different. The name still has external linkage, and the program behaves as if there's only one definition (for example, the function has the same address everywhere, and only one instance of any static variables). The effects of inline
are:
Your code breaks the second rule, which might or might not lead to a link error. This is why inline functions usually need to be in headers, if you need to use them in more than one unit.
Upvotes: 6
Reputation: 4203
When you declare a function inline
, only the translation unit that it is defined in (in this case, F2.cpp) has access to this function. If you instead put it in a header file (say F.h), and #include "F.h"
in both F1.cpp and F2.cpp, then the inline
function is defined twice, once in each translation unit. Normally, this would cause a linker error, but since you declared the function inline
, the linker doesn't know about your Modify()
function.
Upvotes: 1