JCMiguel
JCMiguel

Reputation: 185

C - What does this function pointer declaration mean?

I am analyzing some multithreading code. In an initialization function, there is a piece of code like this:

for(i=0;i<MAX_STREAMS;i++){
    cmdStreamTaskPtr[i] = NULL;
}

I understand that syntax, but my problem is in the declaration of cmdStreamTaskPtr. It is defined in the following way, where cmdData_t is a typedef struct and MAX_STREAMS is 5.

static cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void) = {[0 ... MAX_STREAMS-1] = NULL};

I have no idea what this line means. Is it a variable with a default value?

Upvotes: 9

Views: 811

Answers (2)

dbush
dbush

Reputation: 223972

cmdStreamTaskPtr is an array:

cmdStreamTaskPtr[MAX_STREAMS]

Of pointers:

*cmdStreamTaskPtr[MAX_STREAMS]

To functions that accept no arguments:

(*cmdStreamTaskPtr[MAX_STREAMS])(void)

And return a cmdData_t *:

cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void)

And is static:

static cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void)

That array is then initialized with NULL for all array members:

static cmdData_t *(*cmdStreamTaskPtr[MAX_STREAMS])(void) = {[0 ... MAX_STREAMS-1] = NULL};

Note that the initialization syntax [0 ... MAX_STREAMS-1] is not standard C but an extension supported by GCC. It's also redundant in this case because the array is declared as static, meaning it has static storage duration and therefore its elements are implicitly initialized to NULL if not explicitly initialized.

The use of function pointers can be made more clear with a typedef. In this situation, we can create the following typedef:

typedef cmdData_t *(*fp)(void);

This makes fp a typedef for a pointer to a function taking no arguments and returning a cmdData_t *. The array definition can then be changed to:

static fp cmdStreamTaskPtr[MAX_STREAMS];

So now it should be more clear that cmdStreamTaskPtr is an array of fp, where an fp is the previously defined function pointer.

Upvotes: 25

hacatu
hacatu

Reputation: 665

cmdStreamTaskPtr is an array of pointers to functions that take no arguments and return pointers to cmdData_t's. You can tell by reading the declaration as a usage: cmdStreamTaskPtr is subscripted first since subscripting has a higher precedence than dereferencing, then the result is dereferenced, and then the result is called on void (nothing) and if the result of the function call is dereferenced we finally get a cmdData_t. The static storage duration specifier applies to the array and is redundant since global variables are static by default. Moreover, the code {[0 ... MAX_STREAMS - 1]= NULL} uses a ranged designated initializer, which is a gnu extension to the C language, to set everything to null, which is redundant for three reasons: unspecified elements of an initializer list are set to zero automatically, static storage variables are set to zero automatically, and there is code later that sets the array to zero.

Upvotes: -2

Related Questions