Ian Collins <ia******@hotmail.comwrites:
li*****@hotmail.com wrote:
> I am puzzled on this C puzzle:
How to interpret this C statement: sizeof (int) * p
Is that the size of integer type multiplies p or the size of
whatever p points to in integer type?
I think it should be the latter because there are 4 parser tokens
here, sizeof, int, * and p, the first and the second are of same
precedence which are higher than the third and all three operators are
right associativity.
So I would parse the code into sizeof ((int) (* p))
But it does turn right. I have the following test code:
void main() {
It's probably upset at you for the above!
> int pp = 1;
int* p = &pp;
sizeof (int) * p;
}
I use GCC to compile it and get the following error:
main.c:4: invalid operands to binary *
So compiler takes "*" as multiplication.
Do you see at what point I am wrong?
You can't multiply by a pointer, p is an int*
Yes, but there is a valid question buried among a number of
unfortunate errors. Depending on how the expression is parsed, this:
sizeof (int) * p
could be either a multiplication whose left operand is a sizeof:
(sizeof (int)) * p /* legal if p is numeric */
or a sizeof whose right operand is a cast of a dereference:
sizeof ((int) * p) /* legal if p is a pointer to some numeric type */
This is similar to the question of whether a+b*c means (a+b)*c)
or a+(b*c). There is a single correct answer: it means a+(b*c),
because multiplication has higher precedence (binds more tightly)
than addition. Likewise, there's a single correct answer for
"sizeof ((int) (* p))".
The syntax for the sizeof operator is:
sizeof unary-expression
sizeof ( type-name )
The expression "sizeof (int) * p" cannot satisfy either of those.
It obviously can't match the second form, because the expression
doesn't end in a ')' character, but what about the first? Well,
"(int) * p" is an expression, but it's *not* a "unary-expression".
Why? Because the syntax for a unary-expression is:
unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
unary-operator: one of
& * + - ~ !
In fact, "(int) * p" is a cast-expression:
cast-expression:
unary-expression
( type-name ) cast-expression
(All cast-expressions are unary-expressions, but not vice versa).
The other possibitility is that "sizeof (int) * p" is a
multiplicitive-expression. The syntax for that is:
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
Our expression matches the second alternative here. The left operand,
"sizeof (int)", is a unary-expression, which is a cast-expression,
which is a multiplicative-expression. The right operand, "p", is an
identifier, which is a primary-expression, which [skipping a few steps]
is a cast-expression.
You can also make the same argument in terms of relative operator
precedences, but the standard doesn't use that concept.
--
Keith Thompson (The_Other_Keith)
ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"