Does C correctly handle sizeof(...) and sizeof ... in this case? Does C correctly handle sizeof(...) and sizeof ... in this case? c c

Does C correctly handle sizeof(...) and sizeof ... in this case?


In both cases, the last rofl is the variable name. A variable name is in scope as soon as it appears; and for the remainder of the current scope, that identifier in an ordinary context(*) always means the variable name.

The sizeof operator does not introduce any special cases for name lookup. In fact, there are no language constructs that will use the hidden meaning of an identifier.

In practice it is a good idea to not use the same identifier for a type and a variable name.


(*) There are three special contexts for identifiers: label names, structure tags, and structure members. But in all other contexts, all identifiers share a common name space: there are no distinct identifier name spaces for type names versus variable names versus function names etc.

Here is a contrived example:

typedef int A;      // "A" declared as ordinary identifier, meaning a type namestruct A { A A; };  // "A" declared as struct tag and member name -- OK as these are three different name spaces. Member type is "int"A main()            // int main() - ordinary context{    struct A A();   // "A" declared as ordinary identifier, meaning a function name; hides line 1's A    // A C;         // Would be error: ordinary A is a function now, not a typedef for int    struct A B;     // OK, struct tags have separate name space    A:+A().A;       // OK, labels and struct members have separate name space, calls function    goto A;         // OK, label name space}


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-expressionsizeof ( 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 *.


There is no "picking" or "choosing" involved. In both cases the rofl referred to in each sizeof invocation is the variable, not the type, due to scoping rules. The variable is declared at inner scope, and thus overrides the type name. The parenthesization of the argument to the sizeof operator is irrelevant.

Best of luck.