Inline Functions
An inline functon is declared by prefixing the inline keyword before the function declaration.
Function Call Mechanism
During compilation, machine code is generated which consists of executable instructions stored at specific memory addresses. When executing a program, these instructions are loaded into memory and executed sequentially. Function calls involve jumping to another address (the function's entry point) and returning back to the calling location after execution. This process inculdes storing the return address and potentially pushing parameters onto the stack.
Inline functions avoid this overhead by replacing the function call with the actual function body during compilation.
inline int add(int x, int y)
{
return x + y;
}
Comparison Between Inline Functions and Macros
Macros defined using #define perform text substitution rather than actual function calls:
#define SQUARE(x) x*x
This can lead to unexpected behavior due to operator precedence:
int b = SQUARE(4.5 + 7.5); // Results in 4.5 + 7.5 * 4.5 + 7.5
To fix this, parentheses should be used:
#define SQUARE(x) ((x)*(x))
However, even with parentheses, issues arise with expressions involving side effects:
int d = SQUARE(c++); // Increments c twice
Unlike macros, inline functions provide type safety and proper scoping.
Default Parameters
Default parameter values are specified in function declarations from right to left:
int calculate(int a = 10, int b = 20, int c = 30)
{
return a + b + c;
}
When calling the function without arguments, default values are used:
int result = calculate(); // Uses all defaults
Optional Parameters
Parameters without default values must appear before those with defaults:
void example(char a = 'b', int b = 2, const char* c = "xY")
{
std::cout << a << "," << b << "," << c << std::endl;
}
Invalid usage would be:
void invalid_example(char a = 'b', int b, const char* c)
{
std::cout << a << "," << b << "," << c << std::endl;
}
This fails because parameters without defaults cannot follow parameters with defaults.
Placeholder Functions
Functions may contain unnamed parameters for backward compatibility:
void process(int, int value, int)
{
std::cout << value << std::endl;
}
int main()
{
process(1, 2, 3); // All parameters required
return 0;
}
Placeholder parameters allow modifying function signatures without breaking existing code. For instance, if a function originally took three parameters but now only needs one, you can remove the unused parameters while keeping the interface consistent.