Noob <root@127.0.0.1> writes:
> While debugging the output of a configure script, I came across
> the following program, which is refused by gcc.
>
> int main(void)
> {
> int res = sizeof((int));
> return res;
> }
>
> $ gcc -Wall -std=c89 -pedantic mini.c
> mini.c: In function 'main':
> mini.c:3:25: error: expected expression before ')' token
>
> Obviously, the compiler dislikes the double parenthesis
> around a type-name.
[...]
Parentheses are heavily overloaded (used for different syntactic
purposes) in C. They can be arbitrary nested in some cases, but not in
others.
For example, the parentheses in
x * (y + z)
create a parenthesized expression. Any expression or subexpression,
even if it's already a parenthesized expression, can be enclosed in
parentheses; the only effect is to make it a primary expression if it
wasn't one already. So this:
x * ((y + z))
is also valid.
Parentheses are also used to surround function arguments:
func(x, y)
These do *not* create a parenthesized expression. Surrounding them with
a second set of parentheses doesn't create a two-level parenthesized
expression. If you write:
func((x, y))
then that changes the meaning of the inner parentheses which now *do*
form a parenthesized expression) and of the comma (which is now a comma
operator, not a delimiter between function arguments).
Yet another use of parentheses is in a sizeof operator applied to a type
name:
sizeof (int)
These do not create a parenthesized expression, and they're *not*
directly analagous to the parentheses in a function call. Instead,
they're an inherent part of the syntax of a unary-expression:
sizeof ( type-name )
Just as with the parentheses in a function call, surrounding them with a
second set of parentheses:
sizeof ((int))
doesn't create a more deeply nested parenthesized expression,
since there was no parenthesized expression in the first place.
Instead, in this case, it's a syntax error.
A cast expression is another distinct use of parentheses in the language
grammar:
( type-name ) cast-expression
Although the parenthesized type-name in "sizeof (int)" and the parenthesized
expression in "(int)expr" are visually similar, and probably deliberately so,
they result from different grammar productions and are logically unrelated.
The "(int)" prefix in "(int)expr" is informally referred to as a cast operator.
The "(int)" in "sizeof (int)" is *not* a cast operator, it's a distinct
case of a parenthesized type name.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"