First look at these templates.
struct INIWindows{
inline int GetInteger(){
return 100;
}
};
struct INILinux{
inline int GetInteger(){
return 120;
}
};
template <class Reader>
class SettingsManager : public Reader{
};
Edit: Addendum because it was not clear what i was doing.
int main(){
SettingsManager<INIWindows> Settings;
printf("Integer Reads %i\n",Settings.GetInteger());
system("pause");
return 0;
}
Is my understanding correct that this will result in SettingsManager having an inline function called get integer that will then be inlined properly by the compiler?
Is my understanding correct that this will result in SettingsManager having an inline function called get integer that will then be inlined properly by the compiler.
Yes, your understanding is correct. Your methods are going to be placed in the SettingsManager class, without a virtual dispatch, because the base classes (INIWindows and INILinux) do not have virtual methods.
The inline keyword is only a command for the compiler to try to inline the method - nothing else. It is free not to do it.
inline makes no sense inside a class. If you had defined the functions outside a class then it would indicate internal linkage. But in your current code does not serve any purpose whatsoever: all functions defined in a class are inline.
For the compiler, inline simply means that the name is no visible outside the compilation unit. In this regard, it’s similar to global static. Other than that, the compiler is free to perform function call inlining any way it wants.
In particular, the optimiser may choose to replace a call by the contents of a function. This is what you want, but it’s (almost completely) unrelated to the inline keyword, despite its name.
(By the way, this is unrelated to templates and template metaprogramming.)
Related
Suppose we wan't to hint the compiler to inline member function where applicable.
class Base
{
public:
inline virtual f() = 0;
};
class Derived : public Base
{
public:
virtual f() override; // no inline specifier here
};
Do I need to specify inline in Derived::f() or can I omit the keyword and be sure that virtual Derived::f() is the same thing as inline Derived::f() ?
I mean is the inline keyword implicitly specified for Derived::f() or do I need to explicitly type it once again?
Do I need to specify inline in Derived::f() or can I omit the keyword and be sure that virtual Derived::f() is the same thing as inline Derived::f() ?
If you omit the inline keyword in the derived class, it is not inline in the derived class.
I mean is the inline keyword implicitly specified for Derived::f()
No, it is not.
or do I need to explicitly type it once again?
Yes, you do. However, a compiler will most likely generate code for it as though it is a non-inline member function since it is a virtual member function.
What does the inline keyword do?
Modern compilers try to balance the costs of inlining a function with the benefits.
Both the benefits and the costs are pretty clear: When a function gets inlined, there's no overhead to the function call (since there is no function call), and the compiler is able to do optimizations to the body of the function based on the context within which it's being called (since, when it's inlined, it knows that context).
Costs may include increased executable size (if it's a big function), and more instances of the assembly for the body of the function being plastered around the executable.
A rule of thumb is that if a function is big or complex, it probably won't be inlined. If it's small, it probably will be inlined.
This is good. It prevents bloated executables, but still eliminates nearly all the overhead associated with using functions. The time to execute a big, complex function oftentimes dwarfs the cost of the function call, and inlining it would have only minimal benefit.
So what does inline do? The compiler calculates how complex a function is when deciding to inline it. It then compares that calculation to some threshold. If the function is less complex than the threshold, it inlines the function.
The inline keyword basically raises the threshold for that particular function, but what it actually does under the hood varies from compiler to compiler.
Can all function calls be inlined?
If the compiler doesn't know what function is getting called, it can't inline it.
Let's look at an example:
// func_t is a pointer to a function that returns an integer
using func_t = int(*)();
int getNumber(func_t func) {
// The compiler can't inline func(), because it doesn't know
// what func *is*
return func();
}
How does this apply to virtual functions?
A virtual function call is pretty similar to invoking a function pointer, but with a few key differences. If you're invoking it from the base class, the compiler doesn't know ahead of time what function to invoke:
class Base {
virtual int getNum() { return 0; }
};
class Derived {
int value;
void setValue(int v) { value = v; }
int getNum() override { return value; }
};
int getNumFrom(Base& base) {
// The compiler doesn't know whether to call
// Base::getNum() or Derived::getNum(), so it can't inline it
return base.getNum();
}
However, if you're invoking it from a concrete instance of a class (not a reference, and not a pointer, the compiler knows exactly which version is getting called:
int getNumFromDerived() {
Derived d;
// Here, we know that we're calling Derived::getNum()
// so the compiler *can* inline it.
return d.getNum();
}
How should you apply the inline keyword?
You can specify it both in the base class, and in the derived class. Just know that it won't guarantee they get inlined, precisely because sometimes it's impossible to inline a virtual function call.
Are there alternatives?
Because templates preserve type information, the compiler always knows which function to call. It's easy to inline templated function calls, and using them won't add overhead to your program.
If possible, prefer templates over virtual inheritance.
I am making a class which is inherited from std::fstream. I am making a custom eof() function. That function returns the value of a bool internal_eof variable which is set and reset under slightly different conditions than those of the std::fstream::eof(). These conditions are specific to the nature of my application. The value of bool internal_eof is determined by other functions which are not shown here. Since the BufferedFile::eof() function which I'm defining just consists of a single statement to return the bool internal_eof varaible, I've decided to make it an inline function. I'm wondering, can an inline function of the derived class override a noninline function of the base class? What does the standard say? What do you more experienced programmers know anything about this? I don't really have time for testing this manually, because the fstream::eof() and BufferedFile::eof() behave similarly ~85% of the time. There are just some edge cases where this solution is needed, and they are not easy to reproduce. Knowing whether this solution is a viable one is crucial for further development of the project.
class BufferedFile: public fstream {
public:
inline bool eof() const { return internal_eof; }
...
private:
bool internal_eof;
...
};
The original intent of the inline keyword was a hint for the optimizer that a function/method is preferred to be a candidate for inline substitution. However, compilers are free to use inline substitution for any function, even though it's not marked as inline.
In modern compilers, inline is of less use for optimization, but for informing the compiler that a function (and variable, since C++17) definition may occur in several translation units and it should consider them as the same definition. (See inline specifier)
Whichever it is, the inline keyword is a specifier used by the compiler and is not actually part of a method's signature, and virtual methods can be overridden in derived classes as long as their signature is not changed, whether declared as inline or not.
Except main() (It is compiled and executed at run-time, so you can't compile it at compile-time), all valid C++ functions are overridable:
class Base
{
public:
virtual ~Base(); // Virtual destructor...
virtual void example(); // Function is already 'inline' here... So, it is one of the
// cases where the 'inline' specifier is redundant...
// and similar was found in your class...
};
Here, inline is a specifier, like virtual, and is not a type (nor does it give the function the power to become unique), so overriding it is not a problem...
class Derived : Base
{
public:
virtual ~Derived(); // Virtual destructor...
void example() override;
};
See inline to know more about this specifier...
I already asked a similar question but this one is a bit different
I don't want to write a .cpp file for every simple c++ class.
when I write a class definition and declaration in a single .hpp file, the linker complains about multiple definition of member functions which are not implemented inside the body of the class or defined with inline keyboard.
For example this will work but member functions will become inline :
// log.hpp file
#pragma once
#include<iostream>
class log {
private:
static int m_cnt = 0;
public:
void log();
};
inline void log::log() {
std::cout << ++m_cnt << std::endl;
}
So I use templates to get rid of linker complaints and hope that member functions will not become inline(do they ?):
// log.hpp file
#pragma once
#include<iostream>
template<typename T>
class log_t {
private:
static int m_cnt = 0;
public:
void log();
};
template<typename T>
void log_t<T>::log() {
std::cout << ++m_cnt << std::endl;
}
// some random type (int)
typedef log_t<int> log;
And then I can simply use log class in multiple .cpp files without linker complaints.
even when i use this method will member functions become inline ?
While it is in general bad practice to put everything in a single .h file, there are situations where it's more convenient to do so. Especially when defining small classes, and during prototyping phase where the code can change a lot quickly.
I really don't recommend using templates to solve the linking issue, since it's can slow down compilation and leads to confusion: it's like creating a function taking an argument when you except that argument to always have the same value. Anyway, typing inline is shorter than template<typename T> ;)
So you either have to define your methods in the class body or annotate them with inline if defined out of the body. This is equivalent, since C++ automatically adds inline to methods defined in the class body.
Your concern appears to be with the generated code, you probably wonder if the binary is going to grow too much. But everything's cool since regardless of inline annotations, the compiler looks at every function call and decides whether to inline it or generate a call. This means the same function may sometimes be inlined (if called in a loop) and sometimes be called.
Different compilers have different heuristics, but the inline keyword doesn't have a particularly strong influence on the compiler's decision. You can use things like __forceinline or __attribute__((always_inline)) to make ask more strongly to inline a function, but even then there's no guarantee all calls to the function will be inlined. On the contrary, you may be interested in __attribute__(noinline) for gcc which will (nearly) never inline the call:
inline __attribute__(noinline) void log::log() // gcc
{
std::cout << ++m_cnt << std::endl;
}
If you want to really know what's happening in your code you can use -Winline to see when inline functions are not inlined.
You can also use -Os or -Oz optimization levels to change internal compiler thresholds, so that it will do less inlining.
Related questions which may interest you : here and here.
In general, having every implementation in header files is a BAD idea, since it can lead to very long compile times for larger projects. Using templates to avoid this is not really a good idea, either, since it does not change this fact.
inline is only a hint to the compiler; it may ignore it and inline your template code or not. In short: The answer to your question does not matter. The standard/best way would be to use .cpp files for the implementation, even if you want to avoid it.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When should I write the keyword 'inline' for a function/method?
I am not 100% sure, but as far as I know, if I declare a function on an hpp file with the body it will be treated as it is marked as inline(the compiler will decide what to do), I mean:
//myfile.hpp
class StackOverflow{
public:
void overflow(){_overflow = true;}
...
}
would be the same than:
//myfile.hpp
class StackOverflow{
public:
***inline*** void overflow(){_overflow = true;}
...
}
If I am wrong then the question is over, but otherwise, I really like to mark as inline a function even it is not necessary, does general code style guidelines say soemthing about it?
Thanks so much
As the mention of the keyword inline in this context gives no information whatsoever, leave it out. It’s simply visual clutter.
If there were an option to make an inline-defined function non-inline, this would be a different matter (consider private-by-default as such an example): here, it could be argued that even though it’s the default, making the choice explicit makes it easier to understand. But there’s no choice here. No matter what you do, a member function defined inside the body of a class is inline.
In fact, marking it explicitly as inline would be akin to providing other inferred information. You wouldn’t write the following, would you?
#define member
#define function
class StackOverflow{
public:
member function inline void overflow() { _overflow = true; }
}
Defining a function body inside the class definition makes the function implicitly same as marking it with keyword inline.
As a matter of coding style,
Just defining the function body inside the class is not a good practice.
class Foo {
public:
void method(); ← best practice: don't put the inline keyword here
...
};
inline void Foo::method() ← best practice: put the inline keyword here
{ ... }
This C++ Faq explains the rationale:
class Fred {
public:
void f(int i, char c)
{
...
}
};
Although this is easier on the person who writes the class, it's harder on all the readers since it mixes "what" a class does with "how" it does them. Because of this mixture, we normally prefer to define member functions outside the class body with the inline keyword.
The insight that makes sense of this: in a reuse-oriented world, there will usually be many people who use your class, but there is only one person who builds it (yourself); therefore you should do things that favor the many rather than the few.
If you declare a function as inline inside of the class, for one just like the register keyword, it's open for the compiler to determine (it's a suggestion) if it's a wise optimization to make. Generally, it's a rule of thumb to use inline functions programmed inline inside of the class itself, however it can be done in the implementation of the class as well, though is not common and the only benefit it offers is the linkage, should you decide to pass out the .h/.hpp file as an API header.
Suppose I have a class with an two inline functions:
class Class {
public:
void numberFunc();
int getNumber() { return number; }
private:
int number;
};
inline void Class::numberFunc()
{
number = 1937;
}
I instantiate that class and I call both of the functions in the class:
int main() {
Class cls;
cls.numberFunc();
cout << cls.getNumber() << endl;
return 0;
}
I understand that both inline functions are still members of the class, but it is also my understanding that the code within the body of an inline function is just inserted in place of where it was called. It seems that, as a result of that insert, I should not be able to directly access the member variable number because, as far as I know, the code in main() to the compiler would look like:
main() {
Class cls;
cls.number = 1937;
cout << cls.number << endl;
return 0;
}
Can someone explain to me why I am still able to access those private members, or correct me on my understanding of inline functions? I know that compilers have the option to ignore the inline on some functions; is that what is happening here?
Output:
1937
The rules for accessing private members of a class are enforced by the compiler on your C++ code. These rules don't apply directly to the output of the compiler, which is the code that a computer exectues.
The inline keyword does mean that programmer thinks that compiler may if it so wants to insert the code at place of call. Compiler may inline other functions too without the keyword. Compiler may think that programmer is fool and ignore the keyword and not inline. It is all by C++ standard.
The inline member function is otherwise quite normal member function. No other privileges or restrictions.
Inlines do not cause errors that the function is defined by multiple compilation units (that include the header file where the inline function is defined). That may be one reason why people write inline functions.
The private access specifier is a restriction on the users of the class(the programmers), not on the compiler. The compiler can do whatever it wants, as long as the observable behavior of the program is the same.