In this question, the answer states that to inline a function for a static library, the function is declared inline in the header file and extern in the source file. However in C++, if this is done, a compiler error (Redeclaration of member is not allowed) is generated. What is the correct way to write a function in so it works the same way as in the C post?
Header:
class Int64
{
uint64_t a;
public:
inline void flip() { a = ~a; }
};
Source:
extern void Int64::flip(); // redeclaration of member is not allowed
In C++, you can declare a function as inline only if function code is available in compile time (if you really want to inline that function code). So you cannot implement function body inside compiled static library which will not be available when you use this static library. If you do so, this function call will be similar to a normal function call.
From cppreference:
2) The definition of an inline function must be present in the
translation unit where it is accessed (not necessarily before the
point of access).
Although, you can define your inline function in your static library header(like header only function).
By the way, remember that inline is just a suggestion. compiler will decide to inline or not. This normally happens when you compile code with optimizations enabled, but especially when you don't optimize your code, you normally see that functions are not inlined.
As an example, check this small static library with containing 2 files:
test.h:
#pragma once
inline int sum(int a, int b)
{
return a + b;
}
int sub(int a, int b);
test.cpp:
int sub(int a, int b)
{
return a - b;
}
When you use this library, sum will be inlined and sub will be a normal normal call. Remember, you can even define sub as inline in library header too (without its body) and it will still be like a normal function call.
Related
There are two implications of using the inline keyword(§ 7.1.3/4):
It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inline merely for #1 is not really needed.
Further w.r.t #2, As I understand when you declare a function as static inline function,
The static keyword on the function forces the inline function to have an internal linkage(inline functions have external linkage) Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these)
Thus such a function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
So, Is using static and inline together on a function practically useless?
Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inline just to describe intent.
Disregarding interaction with inline, static functions should be used sparingly. The static modifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
There's no notion of preference. static implies that different functions with the same signature may exist in different .cpp files (translation units). inline without static means that it's OK for different translation units to define the same function with identical definitions.
What is preferred is to use an unnamed namespace instead of static:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Static and inline are orthogonal (independent). Static means the function should not be visible outside of the translation unit, inline is a hint to the compiler the programmer would like to have this function inlined. Those two are not related.
Using static inline makes sense when the inlined function is not used outside of the translation unit. By using it you can prevent a situation of accidental violation of ODR rule by naming another inlined function in another tranlation unit with the same name.
Example:
source1.cpp:
inline int Foo()
{
return 1;
}
int Bar1()
{
return Foo();
}
source2.cpp:
inline int Foo()
{
return 2;
}
int Bar2()
{
return Foo();
}
Without using static on Foo (or without using an anonymous namespace, which is preferred way by most C++ programmers), this example violates ODR and the results are undefined. You can test with Visual Studio the result of Bar1/Bar2 will depend on compiler settings - in Debug configuration both Bar1 and Bar2 will return the same value (inlining not used, one implementation selected randomly by the linker), in Release configuration each of them will return the intended value.
I may not be completely right about this, but as far as I know declaring a function static inline is the only way to make (or allow) the compiler to generate a machine code where the function really is not defined in the compiled code at all, and all you have is a direct substitution of the function call into a sequence of instructions, like it were just a regular procedure body, with no trace in the machine code of a procedure call relative to that function definition from the source code.
That is, only with static inline you can really substitute the use of a macro, inline by itself is not enough.
A simple Google search for "static inline" will show you compiler documentation pages that talk about it. I guess this should be enough to answer your question, and say, "no, it is not practically useless". Here is one example of a site discussing the use of inline, and specifically of static inline http://www.greenend.org.uk/rjk/tech/inline.html
If you talk about free functions (namespace scope), then your assumption is correct. static inline functions indeed don't have much value. So static inline is simply a static function, which automatically satisfies ODR and inline is redundant for ODR purpose.
However when we talk about member methods (class scope), the static inline function does have the value.
Once you declare a class method as inline, it's full body has to be visible to all translation units which includes that class.
Remember that static keyword has a different meaning when it comes for a class.
Edit: As you may know that static function inside a class doesn't have internal linkage, in other words a class cannot have different copies of its static method depending on the translation (.cpp) units.
But a free static function at namespace/global scope does have different copies per every translation unit.
e.g.
// file.h
static void foo () {}
struct A {
static void foo () {}
};
// file1.cpp
#include"file.h"
void x1 ()
{
foo(); // different function exclusive to file1.cpp
A::foo(); // same function
}
// file2.cpp
#include"file.h"
void x2 ()
{
foo(); // different function exclusive to file2.cpp
A::foo(); // same function
}
I just read a man page for gcc and it specifically states the use of static inline with a compiler flag. In the case of the flag, it inlines the function and if it is also static and is inlined in every instance that it is called, then it gets rid of the function definition which will never be used in the created object file, thereby reducing the size of the generated code by that little bit.
For free (NOT inside classes) functions:
static implies inline?
inline implies static?
Or both?
Considering examples:
static void foo1() { ... };
static inline void foo2 { ... };
inline void foo3() { ... };
What the difference?
There are differences, consider (in header):
static int foo1() { static int i = 0; return ++i; }
static inline int foo2() { static int i = 0; return ++i; }
inline int foo3() { static int i = 0; return ++i; }
and in 2 cpp "void caller[1-2]_foo[1-3]() { std::cout << foo[1-3]() << std::endl; }".
So
int main()
{
caller1_foo1(); // 1
caller2_foo1(); // 1
caller1_foo2(); // 1
caller2_foo2(); // 1
caller1_foo3(); // 1
caller2_foo3(); // 2
}
Demo
I cannot found differences between static and static inline though.
No, inline does not imply static not vice versa. See inline nad static description.
(S) Static tells the compiler that the code is only used from this module. You may even get an "unused" warning if you don't use it.
(I) Inline tells the compiler to "try harder" to inline the code. It is not a guarantee, either way, but compilers have various options and pragmas to control this.
If the compiler decides to inline it in this module, then everyone is happy. If the method is also used in another (source) module, that module will decide for itself what to do.
(sI) If the compiler decides not to inline the non-static function, then it will exist as a stand-alone function.
(SI) The presence of 'static' has an effect. If it is static, the name is not emitted to the linker: another module would generate another function with the same name, perhaps from the same source, perhaps not. If it is not static then the compiler will emit the symbol to the linker. If another module also decides not to inline, then it will be emitted twice, and the linker handles this by just picking one (seemingly at random for dynamic linking)!
(Si) Use of static duplication can improve code locality, where non-static code pays for non-locality in all but 1 call. Non-locality is not really a big issue, however. This does also apply to inline tagged methods the compiler decides not to inline.
(si) Note that a non-static non-inline function that the compiler decides to inline anyway has to be emitted as a non-inlined function to the linker as well as the inlined code, in case some other module should extern to it. The linker can discard this function if it is not referenced externally (or exported)
Does it make much difference? probably not!
The following code segment compiles with no problems, even though foo is defined inline but not declared as such, and bar is declared inline but not defined as such.
int foo();
inline int foo() { return 3; }
inline int bar();
int bar() { return 4; }
inline int foobar();
inline int foobar() { return 5; }
int main(){
// ...
}
My first question: does the compiler read foo as inline or not? What about bar? Is this specified by the C++ standard?
My second question: Which one of these is the best practice in declaring and defining inline functions? Is it foo? bar? or foobar? Why?
inb4 I read some other posts related to this but none of them answer my question directly.
This answer seems to suggest that foo is inline, but says nothing about bar. It also doesn't explain why foo is preferred over the others. This answer talks about when I should use inline functions. That's not my concern: I've already decided to use inline functions. My question (question 2, to be precise) is whether I should declare it as such, define it as such, or both, and why one of the conventions is better style than the rest. This question seems to be closer to my concern but nobody answered it.
True for member functions, and not explicitly-defined for non-member functions (I believe)
See §10.1.6 in ISO C++ std.
The inline specifier can be applied only to the declaration or
definition of a variable or function
and
A function declaration (11.3.5, 12.2.1, 14.3) with an inline specifier declares an inline function.
It doesn't explictly state what will happen if an inline specifier only modifies the definition of a function.
What we can be sure of is that such member functions are guaranteed to be marked as inline (thanks to James Curran).
See §12.2.1.
An inline member function (whether static or non-static) may also be
defined outside of its class definition provided either its
declaration in the class definition or its definition outside of the
class definition declares the function as inline or constexpr.
All three functions in GCC and non-member circumstance
As in GCC -O1 C++ mode, every function mentioned are inlined.
Code:
#include "stdio.h"
int foo();
inline int foo() {int i; for(i=0;i<100000;i++); return i+3; }
inline int bar();
int bar() {int i; for(i=0;i<100000;i++); return i+4; }
inline int foobar();
inline int foobar() {int i; for(i=0;i<100000;i++); return i+5; }
int foobar2();
int foobar2() {int i; for(i=0;i<100000;i++); return i+6; }
int main(){
int a,b,c,d;
a=foo();
b=bar();
c=foobar();
d=foobar2();
printf("%d %d %d %d", a, b, c, d);
}
Disassembly:
We can see only foobar2 is called.
As in -O2 and -O3, inline doesn't matter so much. The compiler will decide by itself (in the case above, all 4 functions are inlined).
(NOTE: I reopened this question, as this is NOT a duplicate of the cited older question. That question involved design; this is about syntax).
Now, referring to the question cited by the OP in his question about inline in definition and declaration, the answer states that if the declaration is in a header file, then it was have the "inline" ("bar style"), because other source files using that header will try to link to it as if it were a non-inlined function and file.
Personally, I'd use
inline int foobar() { return 5; }
in the header file without a separate declaration. (I always feel that if it's too big to be in the header, then it's too big to be inlined.)
Consider the following four member function declarations and definitions:
// ==== file: x.h
#ifndef X_H
#define X_H
class X {
public:
int a(int i) { return 2 * i; }
inline int b(int i) { return 2 * i; }
int c(int i);
int d(int i);
};
inline int X::c(int i) { return 2 * i; }
int X::d(int i) { return 2 * i; }
#endif
For completeness, here's the .cpp file that instantiates an X and calls the methods...
// ==== file: x.cpp
#include "x.h"
#include <stdio.h>
int main() {
X x;
printf("a(3) = %d\n", x.a(3));
printf("b(3) = %d\n", x.b(3));
printf("c(3) = %d\n", x.c(3));
printf("d(3) = %d\n", x.d(3));
return 0;
}
My question: are there any salient differences among the four methods? I understand from a comment in this post that the compiler may automatically inline methods that are defined in the class definition.
update
Many answers assume that I'm asking about the difference between inlining and not. I'm not. As I mentioned in the original post, I understand that defining a method in the header file gives the compiler license to inline the method.
I also (now) understand that method d is is risky as written: since it is not inlined, it will be multiply defined if there are multiple translation units.
My question remains: are there any salient differences among the four methods? (As noted, I know that method d is different). But -- just as important -- are there stylistic or idiomatic considerations that would make a developer choose one over the others?
Since this answer keeps getting upvotes, I feel obligated to improve it. But much of what I'm adding has already been stated in other answers and comments, and those authors deserve the credit.
On the subject of whether there's a difference between placing a function body inside the class definition or just below it (but still in the header file), there are 3 different cases to think about:
1) The function is not a template and is not declared to be inline. In this case it must be defined in the class definition or a separate cpp or you will get a linker error as soon as you try to include the h in more than one compilation unit.
2) The function is a template, but is not declared inline. In this case, putting the body within the class definition provides a hint to the compiler that the function can be inlined (but the final decision is still at its own discretion).
3) The function is declared to be inline. In this case there is no semantic difference, but it may sometimes be necessary to place the function body at the bottom in order to accommodate dependency cycles.
Original answer, which provides good info but does not address the actual question:
You've already noted the inline difference. In addition, defining member functions in the header means your implementation is visible to everyone. More importantly, it means everyone who includes your header also needs to include everything needed to make your implementations work.
If you are going to inline it regardless, then you'd move it out of the class if you want to be able to see all your members in one screen, or you have a cyclic dependency as mentioned below. If you don't want to inline it, then you have to move it out of the class and into an implementation file.
In the cases of classes that cyclically refer to each other, it may be impossible to define the functions in the classes so as to inline them. In that case, to achieve the same effect, you need to move the functions out of the classes.
Doesn't compile:
struct B;
struct A {
int i;
void foo(const B &b) {
i = b.i;
}
};
struct B {
int i;
void foo(const A &a) {
i = a.i;
}
};
Does compile, and achieves the same effect:
struct B;
struct A {
int i;
inline void foo(const B &b);
};
struct B {
int i;
inline void foo(const A &a);
};
inline void A::foo(const B &b) {
i = b.i;
}
inline void B::foo(const A &a) {
i = a.i;
}
Oops, just realised you had the definitions in the header file. That creates problems if the include file is included in more than one place.
If the functions are defined in a CPP file then there is no difference.
The only time it makes sense to implement a function inline is when the function is very clearly trivial and/or it has performance implications.
For all other times, it's best to put them in a .cc file and keep its implementation not exposed to the user of the class.
As pointed out by user3521733, it is impossible to implement some functions in the header file when there are cyclic dependencies. Here you are forced to put the implementations in a .cc file.
Update
As far as the compiler, and the runtime, is concerned, there is no difference that I can think of between defining the function inside the body of the class or outside if you use inline when defining it outside the body of the class.
X::a, X::b and X::c are all inlined. X::d is not. That's the only real differnce between these functions, aside from the fact that they are all different functions. The fact that X::c is defined in the header is irrelevant. What is relevant there is that the definition is marked inline.
In order to understand what the differences are, it's important to understand what inline is and is not. inline is not a performance tweak. It's not about making your code faster, and it's not about blowing the code out inline.
What it is about is the ODR. A function marked inline will have the exact same definition in each translation unit where it is used.
This comes in to play when you try to #include your file above in two or more CPP files and call X::d in those translation units. The linker will complain that X::d is defined more than once -- you've violated the ODR. The fix to this is to either mark the function inline or move the definition to it's own translation unit. (eg, to a CPP file)
I have three files:
1. Joy.h
class Joy
{
public:
void test();
};
2. Joy.cpp
#include "Joy.h"
inline void Joy::test() {}
3. main.cpp
#include "Joy.h"
int main()
{
Joy r;
r.test();
return 0;
}
I try to compile them using:
g++ cpp Joy.cpp
g++ say:
main.cpp:(.text+0x10): undefined reference to `Joy::test()'
Who can tell me why...
How to solve this problem if I don't want to define that test() function in the .h file and still want it to be an inline function?
when you define an inline member function, you should prepend the member function's definition with the keyword inline, and you put the definition into a header file.
When you declare a function inline basically You are telling the compiler to (if possible)replace the code for calling the function with the contents of the function wherever the function is called. The idea is that the function body is is probably small and calling the function is more overhead than the body of the function itself.
To be able to do this the compiler needs to see the definition while compiling the code which calls the function this essentially means that the definition has to reside in the header because the code which calls the function only has access to the header file.
Good Read:
[9.7] How do you tell the compiler to make a member function inline?
From the standard (N3242, 7.1.2.4):
An inline function shall be defined in every translation unit in which
it is used and shall have exactly the same definition in every case.
Have a look here as well: How do you tell the compiler to make a member function inline?
The compiler needs the complete definition of the function so that it could be inlined where it is called from. That is possible only if you define it in the header itself.
How does inline function work?
Say, you define this:
inline void increment(int &i) { ++i; }
and then use it as:
int i = 0;
while( i < N )
{
std::cout << i << std::endl;
increment(i);
}
then the compiler translates this code into this (roughly speaking):
int i = 0;
while( i < N )
{
std::cout << i << std::endl;
++i; //replaced the call with the equivalent code which the function
//actually executes to produce the same effect
//(edit typo) it replaces to ++i and not i++ as it was the original.
}
Such replacement of function-call with the code of function itself is said to be inlined. You can say, the function is inlined.
Note that the inline keyword is just a hint for the compiler : it tells the compiler if possible inline me. It is not guaranteed that every inline function call will be inlined by the compiler.
Because of the way C++ is compiled in to separate compilation unit (each cpp file typically), the compilation of one cpp file know not of the implmentation of the inlined function in another compilation unit so can't inline it.
The solution is to put the implementation of the inlined function in the header file this way all files using the head have access to the implementation,
an inline function is a function upon which the compiler has been requested to perform inline expansion.
Hence, the whole point of an inline function is that it is implemented in line. There isn't any way to define it in another source file if you still want it to be an inline function.