Gui13
Gui13

Reputation: 13551

What is (void (**) ()) and how to typedef it?

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

Answers (5)

V-X
V-X

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

Remo.D
Remo.D

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:

  • a pointer to
  • a pointer to
  • a function returning
  • void

Upvotes: 1

unwind
unwind

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

RichieHindle
RichieHindle

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

Steve Jessop
Steve Jessop

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

Related Questions