In this declaration
rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
the name of the variable rofl
hides the typedef name rofl
. Thus in the sizeof operator there is used the pointer rofl
that is the expression has the type int *
.
The same is valid for this declaration
rofl * rofl = malloc(sizeof *rofl);
except that there is used an expression with the dereferenced pointer rofl
that has the type of the typedef name rofl
that is the type int
.
It seems that the confusion arises due to this C grammar definition
sizeof unary-expression
sizeof ( type-name )
However unary-expression
can be a primary expression that is an expression enclosed in parentheses.
From the C Standard (6.5.1 Primary expressions)
primary-expression:
( expression )
//...
So for example if x
is a name of a variable then you may write either
sizeof x
or
sizeof( x )
For clarity you could insert blanks between the sizeof operator and the primary expression
sizeof ( x )
operator primary expression
For comparison consider another unary operator: the unary plus. You can write for example
+ x
or
+ ( x )
Now just substitute the unary plus for another unary operator sizeof
.
As for hiding names the problem is resolvable for structures, unions and enumerations because their names include keywords for tags.
For example
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( struct rofl));
}
In this function with the sizeof operator there is used type-name struct rofl
.
While in this function
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( rofl));
}
with the sizeof operator there is used a primary expression with the variable rofl
, that has the type struct rofl *
.