473,408 Members | 2,813 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Question on precedence

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
7 1933
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: gouqizi.lvcha | last post by:
I have a statement as follows, a = b++; why b=b+1 after a=b. I check the C language precedence (K&R Page 52) , ++ should has higher precedence than = . Rick
8
by: der | last post by:
Hello all, I've a question about order of evaluations in expressions that have && and || operators in them. The question is: will the evalution go left-to-right, no matter what -- even if the...
6
by: Bo Sun | last post by:
hi: please take a look at the following code: int p={111, 222, 333, 444}, *q = p, p1, p2, p3; p1 = *q++; p2 = *(q++); p3 = *(++q);
26
by: myName | last post by:
a && b || c is evaluated as (a && b) || c or it is evaluated as a && (b || c)
3
by: maadhuu | last post by:
hi, i am a bit confused as to how *i++ (i is a pointer) works.....the postfix + has a higher precedence than prefix ++ and i think precedence is from left to right whereas ,prefix ++ and * have...
21
by: siliconwafer | last post by:
Hi, In case of following expression: c = a && --b; if a is 0,b is not evaluated and c directly becomes 0. Does this mean that && operator is given a higher precedence over '--'operator? as...
56
by: spibou | last post by:
In the statement "a *= expression" is expression assumed to be parenthesized ? For example if I write "a *= b+c" is this the same as "a = a * (b+c)" or "a = a * b+c" ?
5
by: fdmfdmfdm | last post by:
Associativity in C takes two forms: left to right and right to left. I think the K&R book lacks something... For example, *p++, since the associativity is from right to left, do this expression...
25
by: mdh | last post by:
Given the expression: while (isaspace(c = *s++)) x+1; (s is an array) Does the increment to 's' occur after "x+1" is evaluated, or after the content of s is assigned to c? Is there a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.