Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A default parameter is a value specified in a function declaration that the compiler automatically injects into a function call when the caller omits the corresponding argument. It allows a function to be invoked with fewer arguments than it declares, effectively instructing the compiler to perform argument substitution at the call site during compile time.
// Syntax
return_type function_name(type param1, type param2 = default_value);

Positional Rules (Right-to-Left)

Default arguments must be strictly trailing. If a parameter is assigned a default value, all subsequent parameters to its right in the lexical scope must also be assigned default values. The C++ standard mandates this because function arguments are resolved positionally from left to right.
// VALID: Trailing parameters have defaults
void process(int a, int b = 2, int c = 3);

// INVALID: Missing default for 'c' after 'b' provides one
void process(int a, int b = 2, int c); 

Redeclaration Rules

According to C++ redeclaration rules ([dcl.fct.default]), a default argument cannot be redefined for a parameter in the same scope, even if the value is identical. Standard practice dictates placing the default argument in the forward declaration (typically in the header file) and omitting it in the function definition (the source file).
// header.h (Declaration)
void configure(int timeout, bool logging = true);

// source.cpp (Definition)
// Do NOT redeclare the default value here.
void configure(int timeout, bool logging) {
    // Implementation
}
If a default parameter is redefined in the definition within the same scope, the compiler will emit an error. However, you can add default arguments to subsequent declarations in the same translation unit, provided they do not redefine existing defaults.
void execute(int x, int y, int z = 10);
void execute(int x, int y = 5, int z); // Valid: adds default to 'y'

Evaluation Mechanics

Default arguments are evaluated at the call site, not at the declaration site. The expressions used for default parameters are bound at compile time but executed at runtime every time the function is called without that argument.
int generate_id();
void register_node(int id = generate_id()); 

// generate_id() is invoked twice at runtime
register_node(); 
register_node(); 

Interaction with Overload Resolution

Default parameters participate in overload resolution and can introduce ambiguity if an overloaded function signature matches the signature of a function utilizing default parameters.
void print(int x);
void print(int x, int y = 10);

// ERROR: Ambiguous call to overloaded function. 
// The compiler cannot determine if it should call print(int) 
// or print(int, int) with the default parameter.
print(5); 

Virtual Functions and Static Binding

When default parameters are used with virtual functions, the default value is statically bound based on the static type of the pointer or reference used to make the call, not the dynamic type of the object.
#include <iostream>

class Base {
public:
    virtual void display(int x = 1) { std::cout << "Base: " << x << '\n'; }
};

class Derived : public Base {
public:
    // Overrides function, but default parameter is statically bound
    void display(int x = 2) override { std::cout << "Derived: " << x << '\n'; }
};

int main() {
    Derived d;
    Base* b = &d;

    // Calls Derived::display() due to dynamic dispatch, 
    // but uses Base's default argument (1) due to static binding.
    b->display(); // Output: "Derived: 1"
    
    return 0;
}
Master C++ with Deep Grasping Methodology!Learn More