Search code examples
cfunction-pointers

Complex type declaration with an anonymous profile as a parameter


I read one Russian book about c-programming. I ran into a question. There is the function with such type:

int (*replace_f(int (*func)(int, int)))(int, int)

This function gets a pointer of function with type "int (int, int)" and returns a pointer of the function with the same type. One important note, neither of the two identifiers(replace_f,func) wasn't declared anywhere in the code before. It's a correct declare and I understand it. But then, the author claims if we need to declare the type pointer to the early function we have to declare as:

int (*(*ptr_replace)(int ( * )(int, int)))(int, int);
not as 
int (*(*ptr_replace)(int ( *func )(int, int)))(int, int);
or
int (*(*ptr_replace)(int ( *any_other_identifier )(int, int)))(int, int);

In other words, we definitely have to write an anonymous type int(*)(int, int)) But any of the cases is working and compiling successfully. He claims that it's not available to use two or more identifiers in the type declaration. Why does it work then?


Solution

  • In int (*replace_f(int (*func)(int, int)))(int, int);, the declaration of func has function prototype scope because it appears inside a function declaration. So this declaration declares two identifiers, replace_f and func, but the scope of func ends at the end of the function declaration.

    That makes func useless in this case. There are situations where an identifier in function prototype scope is useful, such as void foo(int x, int y, float a[x][y]);, where x and y are used to describe the dimensions of a.

    But then, the author claims if we need to declare the type pointer to the early function we have to declare as: … not as …

    This is incorrect. You can declare ptr_replace in any of the three ways shown.

    He claims that it's not available to use two or more identifiers in the type declaration. Why does it work then?

    It does work to declare replace_f. It does not work to declare func or any_other_identifier. So perhaps the original text meant something like this?