Reputation: 3117
If you have function call with constants, it has no side effects and it is not dependent on anything, like the following:
int foo(int a,int b) { return a+b; }
Does the function get inlined? Or, perhaps is the function evaluated at compile-time, with the result of this evaluation inserted in place of the function call?
Upvotes: 4
Views: 904
Reputation: 188
Possible scenario how this function can be calculated in compile time:
1) compiler inline foo
function during one of inlining optimization phase.
2) during constant propagation optimization phase compiler can "propagate" value of variables that are known in compile-time, i.e. constants and constant expression.
NB: You'll never know exactly whether the function is inlined until you see the assembler code of your program. Even if you use inline
specifier. Compiler may ignore this specifier or inline function without this specifier.
Upvotes: 0
Reputation: 21910
If you define that in the header file, then there's a great chance of it being inlined. If you're using integral compile-time constants as its arguments, then the compiler should be able to execute that function on compile-time.
Even though there is no such guarantee, you should trust your compiler. Their pretty good at optimizing your code. If you want to ensure that the function is executed on compile time, you can add a constexpr
overload(C++11 only):
constexpr int foo(int a,int b){
return a+b;
}
I've tried the following snippet:
int add(int a, int b) {
return a + b;
}
int main() {
return add(5, 2);
}
When compiled using GCC and the -O3 flag, it gets compiled to this:
0x08048300 <+0>: mov $0x7,%eax
0x08048305 <+5>: ret
Therefore, you can see that it is actually being executed on compile time.
Upvotes: 2
Reputation: 24477
Whether such optimisations are performed are not a defined part of the C and C++ languages. Essentially, the compiler is free to optimise as it sees fit as long as the resulting code is valid according to the source. In the general case, at higher optimisation levels, this call could be either inlined or if the call sites always pass in constants (values known at compile time), the result can be calculated at compile time and any runtime overhead completely avoided.
The general cases under which case an optimising compiler will choose not to inline functions are:
One more issue to note is that inlining will change the linkage of a function.
Compiling the following C code on both GCC and G++ with -O3
:
int foo(int a, int b) {
return a+b;
}
int main(void)
{
return foo(1, 2);
}
Results in the following assembly code:
00000000004004e0 <main>:
main():
4004e0: b8 03 00 00 00 mov $0x3,%eax
4004e5: c3 retq
Upvotes: 1
Reputation: 30055
I tried compiling this using a fairly old gcc -
#include <iostream>
int foo(int a,int b)
{
return a+b;
}
int main()
{
std::cout << foo(100, 123) ;
}
And main compiled to this -
LFB1439:
subq $8, %rsp
.LCFI1:
movl $223, %esi
movl $_ZSt4cout, %edi
call _ZNSolsEi
xorl %eax, %eax
addq $8, %rsp
ret
So it compiled the addition at compile time getting 223.
Obviously the results depend on your code and compiler but this shows that it can and does both inline and compute the addition at compile time if it can.
Upvotes: 6
Reputation: 69773
It depends on the compiler and on the optimization settings, but in general you can assume that any sufficiently advanced compiler will inline such a trivial function when you switch on at least a bit of optimization.
When you want to make sure that the function is inlined, you can always declare it with the inline keyword:
inline int foo(int a,int b){
return a+b;
}
but such well-intended hints should generally be avoided, because most compilers are better at deciding which functions to inline than most programmers.
Upvotes: 0
Reputation: 1929
you can check the assembly listing to see if it gets inlined, but as mentioned earlier, it is compiler specific.
Upvotes: 0
Reputation: 12335
Not in C++. They will not be executed at compile time just like that - unless the compiler magically does it. However, this cannot be forced.
However, with C++11, you can use constexpr
to ensure it is evaluated at compile time, eg:
constexpr int get_five() {return 5;}
Thus, you can rewrite your function as:
constexpr int foo(int a,int b)
{
return a+b;
}
Note that you do not have to worry if the arguments to this function are not always constant.
From Wikipedia:
If a constexpr function or constructor is called with arguments which aren't constant expressions, the call behaves as if the function were not constexpr, and the resulting value is not a constant expression. Likewise, if the expression in the return statement of a constexpr function does not evaluate to a constant expression for a particular invocation, the result is not a constant expression.
This means that foo(1,1)
will be constant, but:
int i,j;
cin >> i >> j;
foo(i,j) // this is not constant
Reference: http://en.wikipedia.org/wiki/C%2B%2B11#constexpr_-_Generalized_constant_expressions
Upvotes: 4