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 *
.
sizeof
is an operator, not a function, so the parentheses are merely redundant. – Katelynsizeof
operand to have only one option: It must be a “unary-expression” of some sort, so it cannot be a typedef name. In regard to question 1, the parentheses do not cause the compiler to require a typedef name. The thing in parentheses, if it is just an identifier, can only validly be the name of one typedef, function, or object at that point, so the compiler will only find one resolution; it does not need to choose. – Coalitionsizeof (foo)
can match either the “sizeof
unary-expression” shown in clause 6.5.3 of the C standard or the “sizeof (
type-name)
” in the same clause. The match is then determined by which meaning the identifier has, not by local syntax. Without parentheses, only the first is possible. – Coalitionrofl
in the same scope; the variable name hides the type name. Also note that if the typedef were in the function, the variable could not be defined in the same scope. (That's moderately carefully worded to allow a nested scope to (re)define the type or define variables of the same name as the type in the outer scope.) – Lynnlynna