Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does (*) mean in plain C?

Tags:

c

pointers

I can't get the meaning of the "(*)" expression in the following statement:

#define PySpam_System \
 (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])

where

#define PySpam_System_NUM 0
#define PySpam_System_RETURN int
#define PySpam_System_PROTO (const char *command)

(excerpt from http://docs.python.org/2/extending/extending.html). What could that mean? (Excuse me for a dumb question). Resembles a function pointer, but with a very confusing syntax.

UPDATE: Thanks to Shahbaz and Jonathan things are getting mostly clear, but I still can't get two nuances:

  1. Why const char *command, not just const char *. I thought that the name of the argument should be omitted in function pointer type declaration and type conversion? So it must not be omitted, but rather just can be?
  2. Why (*(int (*)(const char *command)), not just (int (*)(const char *command)? What's the purpose of the outer (*[everything else here])? It's the optional dereferencing of function pointer to the function itself, right?
like image 256
Boris Burkov Avatar asked Apr 10 '13 16:04

Boris Burkov


1 Answers

PySpam_System_RETURN (*)PySpam_System_PROTO

expands to:

int (*)(const char *command)

This is a function pointer type. So basically the following:

(*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])

which translates to:

(*(int (*)(const char *command)) PySpam_API[0])

is calling the value of PySpam_API[0] as if it's a function with a const char* argument and an int return value (cast to function pointer). Note that this is still missing the arguments, so whoever uses the macro should give it arguments, such as:

PySpam_System("some string");

On your update:

  1. The argument name is optional. They could have just written const char *. I believe the name was written for clarity. Right now, without looking anywhere else, I understood that the function takes a command, so it was helpful I'd say.
  2. Again, you are right. The initial * dereferences the function pointer. In C, that's quite optional. It would be more symmetrical to put it, since you are dereferencing a pointer, but since not dereferencing a function pointer doesn't make sense, if you don't dereference it wouldn't make any difference, C would do the only sane thing for you. In fact, even if you put ****** instead of just one, it would still work.
like image 184
Shahbaz Avatar answered Oct 03 '22 17:10

Shahbaz