Reputation: 185
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
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
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