By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,264 Members | 1,743 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,264 IT Pros & Developers. It's quick & easy.

sizeof (char)(char)2

P: n/a
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.
Nov 14 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
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.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html

"C is a sharp tool"

Nov 14 '05 #2

P: n/a
te***@gnu.org (M Welinder) writes:
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
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #3

P: n/a
Emmanuel Delahaye wrote:
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)


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

Nov 14 '05 #4

P: n/a
Emmanuel Delahaye <em***@YOURBRAnoos.fr> wrote in message news:<mn***********************@YOURBRAnoos.fr>...
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
Nov 14 '05 #5

P: n/a

"M Welinder" <te***@gnu.org> wrote in message
news:64**************************@posting.google.c om...
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.

Nov 14 '05 #6

P: n/a
M Welinder wrote:
Emmanuel Delahaye <em***@YOURBRAnoos.fr> wrote in message news:<mn***********************@YOURBRAnoos.fr>...

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


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).

--
Er*********@sun.com

Nov 14 '05 #7

P: n/a
Xenos wrote:
"M Welinder" <te***@gnu.org> wrote in message
news:64**************************@posting.google.c om...
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.


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

--
Er*********@sun.com

Nov 14 '05 #8

P: n/a
te***@gnu.org (M Welinder) wrote:
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.
Nov 14 '05 #9

P: n/a
In message <41**************@sun.com>
Eric Sosman <Er*********@sun.com> wrote:
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 ).

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.