views:

181

answers:

4

They said this expression is valid in C, and that it means calling a function:

(*(void(*)())0)();

Can someone clearly explain what this expression means?

I tried to compile this and was surprised that it didn't result in an error.

+5  A: 

You are creating a pointer to a function and then calling it. I wouldn't call it a hidden feature but undefined behavior.

Basically you are doing this but with the address 0 instead:

void test() { }

void(*pfn)() = test;
(*pfn)();
Brian R. Bondy
+3  A: 

it's a pointer to a function at NULL.

void(*)() is the "definition" of a pointer to a function taking no args and "returning" NULL; you can name it:

typedef void(*my_func)();

then in your example you've got a cast:

(my_func)0 yields a function pointer to a my_func, that is, a function taking nothing and returning nothing.

Then you dereference it with the leading asterisk (which is unnecessary, afaik), and then you call it.

So you're calling a function taking no arguments and returning nothing that happens to live at address zero.

This is (usually) undefined behavior, and will crash instantly on many platforms. (It is not undefined behavior if you put a function at address zero, at least I wouldn't think it was.)

dash-tom-bang
+15  A: 

Step by step:

   void(*)()        // a pointer-to-function type, taking unspecified parameters
                    // and returning nothing.
  (void(*)())0      // a null pointer, cast to that function type
(*(void(*)())0)     // dereference that pointer
(*(void(*)())0)();  // and call it with no parameters

The code has undefined behaviour, it'll probably crash with some kind of illegal access / segfault.

Steve Jessop
// and pick the shrapnel out of your ears afterwards.
Hans Passant
@nobugz: the standard does not require that you still have ears afterwards ;-)
Steve Jessop
The compiler could turn you into a snake, those don’t have ears.
jleedev
@Steve Jessop: Thanks for detail answer
nguyendat
Actually that code would have behavior specific to the platform you're compiling it to. It may be clearly defined for some platforms, and illegal on others. I bought a micro-controller recently, and when it's activated, it executes code starting at address 0 in memory. So that code would jump to the beginning of the program.
Wallacoloo
Right, that micro-controller is one of the cases which means it only *probably* crashes - the probability that nguyendat is using a platform where it won't is low ;-) When I say "undefined behaviour" of course I mean, as always, undefined by the C standard. Particular implementations can make guarantees what they will do in particular cases of undefined behaviour.
Steve Jessop
+2  A: 

Break it down per parenthesis.

The last () signifies a function with no parameters.

The line (void(*)()) means a function that returns void.

The last little bit, the (* at the beginning and the 0) is telling the compiler that the address of the function to call lies at pointer location 0.

So basically, you are calling whatever the heck lies at address 0 with no parameters. Not usually very safe. :)

Michael Dorgan