The syntax used here is not a type, but a composite literal . They are defined in section 6.5.2.5 standard C :
3 A postfix expression consisting of a type name in parentheses followed by a list of initializers enclosed in parentheses is a composite literal. It provides an unnamed object whose value is specified in the list of initializers.
An adjacent literal is required when assigning a struct as a whole.
In this case, you do not need this syntax:
int *a= malloc(sizeof(int)); *a= 4;
Since *a is of type int , and 4 is a simple integer constant that can be assigned directly to *a .
Note also that the fact that the pointer is involved does not matter. In this case, you will need to do the same:
node_bst root; root= (node_bst){0, NULL, NULL, NULL};
This is different from:
node_bst root = {0, NULL, NULL, NULL};
The first case is an assignment, and the second is initialization. Initialization can only be done while the variable is being defined (even outside the function), while assignment can be done at any time.
The initialization syntax (see section 6.7.9 of the standard) allows only a list of values ββenclosed in curly brackets, while a composite literal is required for assignment.
In addition, as mentioned in the comments, you can still use the composite literal in the initialization, and the composite literal has the lifetime of the current area, the address of which you can take.
Here is an interesting example:
char *str = (char[]){ "My string" }; str[3] = 'S';
Here the composite literal changes, which is allowed. But if you do this:
char *str = "My string"; str[3] = 'S';
Instead, you try to change the string literal and most likely get a segmentation error.