Since time immemorial we have at our disposal macros and inline functions:
#define SUMA(a,b) a+b
inline int suma(int a, int b)
{ return a + b; }
However since C++11 it is available constexpr
(whose functionality has been greatly increased in C++14):
constexpr int suma(int a, int b)
{ return a + b; }
What is the difference between these three options? Which option would be more recommended?
MACRO
Macros are a direct inheritance of C. One of the main flaws of macros is that they do not have typing, that is, you can pass any type of data to the macro and if the resulting code is compiled, you will not get errors:
Another problem with the macro is that it will explode the parameters literally, which can give strange results:
Someone might think that the output of this code is going to be:
However the actual output is (in my case):
I have not calculated the first result manually because the final result will depend on the compiler (and the problem is with the postincrement):
The compiler processes the postincrements after the result has been calculated:
The compiler processes
(2*4)
and calculates a postincrement:The compiler processes the equation backwards and computes a postincrement after
(4+1)
:It is easy to guess that this example can be complicated as much as we want:
What's the score? The correct answer is:
For all these problems, macros should be avoided in the vast majority of situations (and others that are not listed).
INLINE FUNCTIONS
To avoid all these problems derived from the macros, the functions arose
inline
. An inline function is strongly typed and guarantees the stability of the parameters (pre-increments, post-increments, etc. are calculated once). The above code using an inline function:The result would now be:
And if we convert the postincrements example:
The result would ALWAYS be :
CONSTEXPR FUNCTIONS
The constexpr functions appeared in the C++11 standard. They are similar to inline functions with the addition that the result of the operation " can " be precomputed at compile time. In itself this may not seem like an obvious advantage, since inline functions can currently also be optimized in the same direction, as shown in the following example:
Whose assembly output (clang 3.9.1 -std=c++11 -O3) is as follows:
There you can see how the result of both functions (
10! = 3628800
) has been precalculated at compile time.What is the difference then between using
inline
orconstexpr
?The difference is that
constexpr
, due to the restrictions that it implements (I do not intend to list them because this post is not a course onconstexpr
), it allows to ensure better optimizations in the code. Let's look at another example:Assembly code:
Here you can see how the function
inline
involves two copy operations (one to store the result invalor1
and one to callfuncExtern
), while in the version caseconstexpr
the compiler has the luxury of directly using the value where it is required.In subsequent standards, the capabilities of
constexpr
have increased, so it is increasingly being reinforced as the most powerful alternative.CONCLUSION
The best thing to do, based on my experience, is to prioritize features
constexpr
. When this route cannot be used, for whatever reason, the second option should be functionsinline
, reserving macros for those situations where the previous two options are not available.