Reputation: 13551
In an embedded code I have to understand, there's this line of code :
*((void (**) ()) 0x01) = c_int01; /* Write the interrupt routine entry */
I can grasp the fact that you setup the interruption vector with the function pointer c_int01
, but I can't figure what kind of cast (void (**) ())
refers to. I know the standard function pointer notation (void (*)())
but not the other one.
I tried to refactor the code so that it looked a bit more readable like this:
// header
typedef void (*interrupt_handler)(); // prototype of an interruption handler
#define INTERRUPT_VECTOR 0x01
#define SET_INTERRUPT_HANDLER( handler ) *((interrupt_handler) INTERRUPT_VECTOR) = (handler)
// code
SET_INTERRUPT_HANDLER( c_int01 );
But the embedded compiler whines about the LHS not beeing an object.
Anybody know what this notation signifies? (void (**)())
// EDIT:
For those interrested, I would understand this much better:
*( (void (*)())* 0x01) = c_int01;
Upvotes: 6
Views: 956
Reputation: 3029
You may visualize the setting of interrupt entry point vector as
void (*interupt_handlers)()[256] = 0;
void set_interupt_handler(int vector, void(*handler)())
{
interupt_handlers[vector] = handler;
}
Upvotes: 0
Reputation: 16522
Cdecl would be the quicker way to know:
cast unknown_name into pointer to pointer to function returning void
The famous "spiral rule would be the next:
+-----+
|+-+ |
|| | V
(void (** |)( ))
^ ^^|| |
| |||| |
| ||+| |
| +--+ |
+---------+
Following the lines you read:
Upvotes: 1
Reputation: 399949
Here's what the ever-useful cdecl says about the core of that expression, the (void (**) ())
:
cast unknown_name into pointer to pointer to function returning void
So, it's a cast (as signified by the outer pair of parentheses), and the type is "pointer to pointer to function", which seems to make sense.
Upvotes: 2
Reputation: 281675
(void (**) ())
is a pointer to a function pointer.
((void (*)())
is a pointer to a function, so adding a star adds a level of indirection.)
You need to say:
*((interrupt_handler*) INTERRUPT_VECTOR) = (handler)
That reads, "Treat INTERRUPT_VECTOR
as a pointer to a function pointer, and set its value to handler
."
Upvotes: 6
Reputation: 279315
It's a pointer-to-pointer-to-function.
So the cast converts the integer 0x01
to the address of a function pointer having type (void (*)())
You could rewrite it:
typedef void (*interrupt_handler)();
*((interrupt_handler*) 0x01) = c_int101;
Upvotes: 12