Search code examples
cfunction-pointersimplicit-conversionfunction-declaration

Why is declaring a function parameter instead of function pointer parameter allowed?


I don't really know what I expect as an answer to this but being able to declare function parameter while not being able to declare variable inside a function the same way makes me uneasy.

#include <stdio.h>

void func(void why_is_this_allowed()) {
    why_is_this_allowed();
}

void func2(void (*this_makes_more_sense)()) {
    this_makes_more_sense();
}

void print() {
    printf("I am stuff\n");
}

int main()
{
    void and_why_is_this_NOT_allowed() = print;
    
    func(print);
    func2(print);

    return 0;
}

Solution

  • Much like how arrays as parameters are adjusted to be pointers, functions as parameters are adjusted to function pointers.

    This is spelled out in section 6.7.6.3p8 of the C standard:

    A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1.

    That means that this:

    void func(void why_is_this_allowed()) {
        why_is_this_allowed();
    }
    

    Is exactly the same as this:

    void func(void (*why_is_this_allowed)()) {
        why_is_this_allowed();
    }
    

    In contrast, this doesn't work:

    void and_why_is_this_NOT_allowed() = print;
    

    Because no such adjustment happens, so and_why_is_this_NOT_allowed is taken to be a function declaration, and such a declaration is not an lvalue and therefore can't be assigned to.