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

Question on precedence

P: n/a
Hi,
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() {
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?

May 12 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
li*****@hotmail.com wrote:
Hi,
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*

--
Ian Collins.
May 12 '07 #2

P: n/a
In article <11**********************@y80g2000hsf.googlegroups .com>,
<li*****@hotmail.comwrote:
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.
Questions like this keep coming up, and the answer is always the
same: C does not use operator precedence to define the grammar,
and tables attempting to summarise the syntax using precedence
are often inadequate. The one you're using seems to be an example,
because sizeof and cast do *not* have the same precedence.

The standard defines the grammar using "production rules". The
operand of sizeof is either a unary-expression or a parenthesised type
name. "(int) * p" does not match the production for unary-expression
and is not a parenthesised type name, so it cannot be the operand of
sizeof.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
May 12 '07 #3

P: n/a
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"
May 12 '07 #4

P: n/a
li*****@hotmail.com writes:
I am puzzled on this C puzzle:
I've answered your actual question in another followup. I'll take
this opportuntiy to point out some errors that might obscure the
question you're trying to ask.
How to interpret this C statement: sizeof (int) * p
That's an expression, not a statement.
Is that the size of integer type multiplies p or the size of
whatever p points to in integer type?
It's the former; see my other followup for the gory details.
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.
There are 6 tokens: sizeof, (, int, ), *, and p.

Tokens don't have precedence. Operators do have precedence, sort of,
but the standard doesn't present expression syntax using that concept.
So I would parse the code into sizeof ((int) (* p))

But it does turn right. I have the following test code:

void main() {
The correct declaration is "int main(void)". If your textbook told
you that "void main()" is correct, get your money back.
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.
Right, and if p had been of some numeric type, it would have compiled
without error.
Do you see at what point I am wrong?
See my other followup.

--
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"
May 12 '07 #5

P: n/a
li*****@hotmail.com wrote some nonsense in which he claimed to have a
reasonable interptetation of:

sizeof (int) * p

His example code begins
void main() {
At this point we know that anything he might opine about C can be safely
ignored.
[...]
Do you see at what point I am wrong?
Yes.
May 12 '07 #6

P: n/a
In article <5a*************@mid.individual.net>,
Martin Ambuhl <ma*****@earthlink.netwrote:
>li*****@hotmail.com wrote some nonsense in which he claimed to have a
reasonable interptetation of:

sizeof (int) * p

His example code begins
>void main() {

At this point we know that anything he might opine about C can be safely
ignored.
[...]
> Do you see at what point I am wrong?

Yes.
All threads on clc either start out as or quickly degenerate into
discussing "void main()".

The point being that it *is* the one thing we can all agree on.

May 12 '07 #7

P: n/a
li*****@hotmail.com wrote:
>
.... snip ...
>
So I would parse the code into sizeof ((int) (* p))

But it does turn right. I have the following test code:

void main() {
int pp = 1;
int* p = &pp;
sizeof (int) * p;
}
Casts are usually errors. p is a pointer to an int, so *p is an
int, and no cast is needed.

main returns an int. Say and do so.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

May 12 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.