sizeof (char)(char)2

M

M Welinder

This doesn't work with any C compiler that I can find. They all report a
syntax error:

printf ("%d\n", (int)sizeof (char)(char)2);

Now the question is "why?" "sizeof" and "(char)" have identical precedence
and right-to-left parsing, so why isn't the above equivalent to

printf ("%d\n", (int)sizeof ((char)(char)2));

It should probably be obvious to me, but right now it isn't.
 
E

Emmanuel Delahaye

M Welinder wrote on 26/07/04 :
This doesn't work with any C compiler that I can find. They all report a
syntax error:

printf ("%d\n", (int)sizeof (char)(char)2);

Now the question is "why?" "sizeof" and "(char)" have identical precedence
and right-to-left parsing, so why isn't the above equivalent to

printf ("%d\n", (int)sizeof ((char)(char)2));

It should probably be obvious to me, but right now it isn't.

Because the type must be enclosed in parenthesis when used with sizeof.

The correct syntax is:

sizeof object
sizeof (type)

sizeof (type) (type)

is not correct C.
 
M

Martin Dickopp

This doesn't work with any C compiler that I can find. They all report a
syntax error:

printf ("%d\n", (int)sizeof (char)(char)2);

Now the question is "why?" "sizeof" and "(char)" have identical precedence
and right-to-left parsing, so why isn't the above equivalent to

printf ("%d\n", (int)sizeof ((char)(char)2));

It should probably be obvious to me, but right now it isn't.

The C standard does not use the concept of precedence, but achieves the
same effect through the use of syntax rules. In terms of precedence,
the `sizeof' operator has higher precedence than the cast operator, i.e.

sizeof (char)(char)2

behaves like

(sizeof (char)) (char)2

which is indeed a syntax error.

Martin
 
U

Ulrich Eckhardt

Emmanuel said:
M Welinder wrote on 26/07/04 :

Because the type must be enclosed in parenthesis when used with sizeof.

The correct syntax is:

sizeof object
sizeof (type)

Right.
sizeof (type) (type)

is not correct C.

Maybe. Firstly, this discussion is purely academic; anybody writing such
code should be LARTed big time.
Now, about the example, I think that it mixes two things:
1. double cast
2. applying sizeof on the result of that cast

What I think is that (provided the precedence the OP claims is really
required) '(char)(char)2' should be evaluated first, and that is in my
understanding an object, which is why the 'sizeof object' syntax applies.

Now, to the OP: which of the above two things that you mixed are really
bothering you? Or is it really the combination that you can't get past any
compiler?

Uli
 
M

M Welinder

Emmanuel Delahaye said:
Because the type must be enclosed in parenthesis when used with sizeof.

The correct syntax is:

sizeof object
sizeof (type)

That misses the point.

Notice that these _are_ valid:

printf ("%d\n", (int)sizeof +(char)(char)2);
printf ("%d\n", (int)sizeof ((char)(char)2));

So to rephrase: why isn't "sizeof (char)(char)2)" parsed as the latter?
It fits "sizeof object" nicely, but it feels like there is some unstated
"dont' do anything an LR(1) parser couldn't handle" rule.

Or even more explictly: what in the C definition precludes
"sizeof (char)(char)2)" being parsed as this?

sizeof
|
typecast-expr
| |
"char" |
typecast-expr
| |
"char" |
int-constant
|
2
 
X

Xenos

M Welinder said:
This doesn't work with any C compiler that I can find. They all report a
syntax error:

printf ("%d\n", (int)sizeof (char)(char)2);

Now the question is "why?" "sizeof" and "(char)" have identical precedence
and right-to-left parsing, so why isn't the above equivalent to

printf ("%d\n", (int)sizeof ((char)(char)2));

It should probably be obvious to me, but right now it isn't.

It has nothing to do with precedence. The C standard says that "sizeof"
followed by a left parenthesis should be parsed as size of type expression.
This is one reason blindly relying on a precedence table is bad. I remember
reading an article on this once in one of the journals. Many wrote in
refusing to believe it. Many of them kept parrots the same crap about
precendence.
 
S

Stefan Ram

Or even more explictly: what in the C definition precludes
"sizeof (char)(char)2)" being parsed as this?

"sizeof" "(" <type-name> ")" already is a complete
<unary-expr>, which can not be followed directly by another
expression.

One can also not interpret "(char)(char)2" as a <unary-expr>
to fit the pattern "sizeof" <unary-expr>, because a
<cast-expr> is not a <unary-expr>.
 
E

Eric Sosman

M said:
That misses the point.

Notice that these _are_ valid:

printf ("%d\n", (int)sizeof +(char)(char)2);
printf ("%d\n", (int)sizeof ((char)(char)2));

So to rephrase: why isn't "sizeof (char)(char)2)" parsed as the latter?
It fits "sizeof object" nicely, but it feels like there is some unstated
"dont' do anything an LR(1) parser couldn't handle" rule.

Or even more explictly: what in the C definition precludes
"sizeof (char)(char)2)" being parsed as this?

sizeof
|
typecast-expr
| |
"char" |
typecast-expr
| |
"char" |
int-constant
|
2

Um, er, "the grammar in the Standard" is what forbids
such a parse. The directly relevant pieces are in 6.5.3
(some forms omitted for brevity):

unary-expression:
postfix-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )

and 6.5.4:

cast-expression:
unary-expression
( type-name ) cast-expression

`sizeof +(char)(char)2' works because `+(char)(char)2'
is a "unary-expression:" it matches the second form in the
above (abbreviated) 6.5.3 list. `sizeof (char)(char)2' fails
because `(char)(char)2' is not a "unary-expression" but a
"cast-expression." (You could observe the same effect with
the shorter `sizeof (short)42'.)

Informally, `sizeof' has higher precedence than casts,
despite what K&R say (in the first edition, anyhow; I don't
have K&R II).
 
E

Eric Sosman

Xenos said:
It has nothing to do with precedence. The C standard says that "sizeof"
followed by a left parenthesis should be parsed as size of type expression.

No, it does not -- in fact, the last line of code you
quoted provides a counter-example.
 
O

Old Wolf

This doesn't work with any C compiler that I can find. They all report a
syntax error:

printf ("%d\n", (int)sizeof (char)(char)2);

Now the question is "why?" "sizeof" and "(char)" have identical precedence
and right-to-left parsing, so why isn't the above equivalent to

printf ("%d\n", (int)sizeof ((char)(char)2));

Because C syntax is defined by a BNF grammar, and the grammar says so.
Any notions of "precedence" and "right-to-left parsing" are just convenient
approximations that humans can digest more easily than BNF, and as this
example shows, aren't always reliable.

Also, don't be too surprised if this example works in C++, as there
are minor differences in their grammars, even for the 'common subset'
of the languages.
 
K

Kevin Bracey

In message <[email protected]>
Eric Sosman said:
Um, er, "the grammar in the Standard" is what forbids
such a parse. The directly relevant pieces are in 6.5.3
(some forms omitted for brevity):

unary-expression:
postfix-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )

and 6.5.4:

cast-expression:
unary-expression
( type-name ) cast-expression

`sizeof +(char)(char)2' works because `+(char)(char)2'
is a "unary-expression:" it matches the second form in the
above (abbreviated) 6.5.3 list. `sizeof (char)(char)2' fails
because `(char)(char)2' is not a "unary-expression" but a
"cast-expression." (You could observe the same effect with
the shorter `sizeof (short)42'.)

Informally, `sizeof' has higher precedence than casts,
despite what K&R say (in the first edition, anyhow; I don't
have K&R II).

In a related vein, I found a nasty in our compiler recently - it was
incorrectly parsing

sizeof (char[]) { "Foo" }

Anyone implementing C99, particularly when adding it to an existing C90
compiler, should check that they handle that correctly; our parser required
some additional code in sizeof to test for the presence of a '{' after (
type-name ).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top