How does function casting really work in C?

int foo(char *c) {...} main() { int (*thud)(void *); thud = (int (*)(void *))(foo); } 

What really happens when evaluating a job?

There is a difference between cast type and foo ; cast is a pointer, and foo is a function. So, does the compiler convert what is into ' (foo) ' into a pointer to foo and only then does it throw? Because nothing else makes sense; another option is that the function itself is converted to a pointer to a function that receives void* and returns int , and as far as I know, the function is a label for a piece of code in memory and, therefore, cannot become a pointer, which is a variable.

+6
c function casting pointers function-pointers
source share
5 answers

The function name is a pointer when used as such. This is somewhat similar to how an array name is a pointer to its first element.

At the same time, calling a function through a pointer with a different type than the actual function prototype (as your example) is undefined behavior. Do not do this.

Adding

If the converted pointer is used to call a function whose type is incompatible with the specified type, the behavior is undefined.

from section 6.3.2.3 of standard C.

+5
source share

In C, absolutely nothing. This is just the glue of the compiler so you don't do something stupid. In C, the caller is responsible for maintaining the stack frame, so actuation is necessary when the function is called (i.e., the arguments and return value are pushed onto the stack). This makes it safe (r) since the caller's stack is likely to be incorrectly changed. However, the called function may still corrupt the caller's stack in some rare cases.

I must clarify that assignment copies a function pointer. But in C, all function pointers are just pointers. Type and casting are all the glue of the compiler.

Another explanation: the standard indicates (in 6.5.2.2) that the behavior is undefined if the caller uses incompatible types. For example, a cast function that returns void to one that returns int, and then calls this function, the "return" value is meaningless. It is recommended that you include the function in a compatible type before calling it, or you may see unexpected results.

+5
source share

A pointer to C is an address, that is, a number stored in some place. A function in C is the address for some code. These two are the same.

+2
source share

The correct term is decay. The function foo decays to a pointer to foo before translation. The cast itself will be non-op on all platforms that I can think of.

Note, however, that the behavior of a program containing such a listing is undefined by the C standard.

+2
source share

This was a comment on Rick C. Petty's answer, but it does not fit into 300 characters.

The C standard is not very restrictive - pointers to objects (and functions are not objects) can be converted to a "pointer to void" and vice versa without problems. POSIX requires function pointers to be the same size and can be converted to a pointer to void.

POSIX 2008 - General Information - Compilation Environment

2.12.3 Types of Pointers

All types of function pointers must have the same representation as a type pointer to void. Converting a function pointer to void * should not change the view. The void * value resulting from such a conversion can be converted back to the original type of the function pointer using an explicit cast without loss of information.

Note: The ISO C standard does not require this, but it is required for POSIX compliance.

+2
source share

All Articles