thecodex.expert · The Codex Family of Knowledge
C

Functions

C has no pass-by-reference at all — every single argument is copied, and the only way to let a function modify a caller’s variable is to explicitly pass its address as a pointer.

C17 / C23 Always pass-by-value Last verified:
Canonical Definition

A C function declares a return type, a name, and a parameter list; void means it returns nothing. Every argument is passed by value — the function receives a copy, and modifying that copy inside the function never affects the caller's original variable. The only way to let a function modify a caller's data is to explicitly pass a pointer to it, so the function can dereference and write through that address. If a function's definition appears later in the file than its first call, a prototype declaring its signature must appear earlier, or the compiler has no way to check the call is correct.

Everything is pass-by-value

double() receives its own copy of x, so multiplying it has zero effect on the caller's original variable — this is true for every C function call, with no exceptions.

Cpass_by_value.c
void double_it(int n) {
    n = n * 2;   // modifies only the LOCAL copy
}

int main(void) {
    int x = 5;
    double_it(x);
    printf("%d\n", x);   // still 5 — double_it never touched the original
    return 0;
}

Passing a pointer to actually modify the caller's variable

Passing &x (x's address) lets the function dereference that address and write through it directly — this is C's only mechanism for a function to affect the caller's own data.

Cpass_by_pointer.c
void double_it(int *n) {
    *n = *n * 2;   // dereference: modifies the ORIGINAL, through its address
}

int main(void) {
    int x = 5;
    double_it(&x);
    printf("%d\n", x);   // 10 — the original WAS modified, via the pointer
    return 0;
}

Function prototypes: declare before use

Without the prototype, calling add() before its definition appears would be a compile error — the compiler needs to know a function's signature before checking any call to it, and a prototype supplies exactly that without needing the full definition yet.

Cprototype_example.c
int add(int a, int b);   // prototype: declares the signature

int main(void) {
    printf("%d\n", add(2, 3));   // fine — the prototype above already declared add()
    return 0;
}

int add(int a, int b) {    // the actual definition, further down the file
    return a + b;
}

Sources

1
ISO/IEC 9899 (C Standard), "Function declarations" and "Function calls," cppreference.com/w/c/language/functions.