473,387 Members | 1,766 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,387 software developers and data experts.

is ++n equivalent to (n=n+1) ?

Hi,

I've gotten into the habit of mentally converting big expressions to
parse tress (started doing this after reading some c.l.c posts on parse
trees).

Can someone verify if the following assumptions are correct?

1) For ++n, one can us (n=n+1) as it's equivalent:

| =
| / \
| n +
| / \
| n 1
2) For assignment operators of the form n op= b, the equivalent tree
is:

| =
| / \
| n op
| / \
| n b

3) For n++, one can use n, but with a side condition that (n=n+1) will
occur somewhere between now and the earliest sequence point up the tree
(but n=n+1 is no physically part of the tree)

|
| n
|
| [Side note: (n=n+1) can occure as a side effect anytime before the
| earliest sequence point up the tree]

Are my assumption correct?

Nov 14 '05 #1
11 1909
In article <11**********************@g14g2000cwa.googlegroups .com>,
Kobu <ko********@gmail.com> wrote:
:I've gotten into the habit of mentally converting big expressions to
:parse tress

:Can someone verify if the following assumptions are correct?

:1) For ++n, one can us (n=n+1) as it's equivalent:

No. Suppose n is an expression that returns an lvalue and which
has side effects. In n = n + 1 then n will be evaluated for both
sides of the assignment, resulting in the side effect being done
twice. In n++ or n op= p n will only be evaluated once.

For example, queuehead()->count = queuehead()->count + 1
differs from queuehead()->count++

--
When your posts are all alone / and a user's on the phone/
there's one place to check -- / Upstream!
When you're in a hurry / and propagation is a worry/
there's a place you can post -- / Upstream!
Nov 14 '05 #2
In article <11**********************@g14g2000cwa.googlegroups .com>,
"Kobu" <ko********@gmail.com> wrote:
Hi,

I've gotten into the habit of mentally converting big expressions to
parse tress (started doing this after reading some c.l.c posts on parse
trees).

Can someone verify if the following assumptions are correct?

1) For ++n, one can us (n=n+1) as it's equivalent:

| =
| / \
| n +
| / \
| n 1
2) For assignment operators of the form n op= b, the equivalent tree
is:

| =
| / \
| n op
| / \
| n b
Correct, except that the lvalue n is only evaluated once. So

++(*++p); ++a [i++];

is absolutely not the same as

(*++p) = (*++p) + 1; a [i++] = a [i++] + 1;
but for a plain variable like n it is correct. (2) is quite important if
you need to figure out exactly what happens for example if you have a
complicated case like

unsigned short us;
double d;

us += d;

In a case like that, all you need to do is to read what exactly (us + d)
does, and then you read the rules what assigning a double to an unsigned
short exactly does. Defining it this way must have saved dozens of pages
in the C Standard.
3) For n++, one can use n, but with a side condition that (n=n+1) will
occur somewhere between now and the earliest sequence point up the tree
(but n=n+1 is no physically part of the tree)

|
| n
|
| [Side note: (n=n+1) can occure as a side effect anytime before the
| earliest sequence point up the tree]


Yes.
Nov 14 '05 #3
Christian Bau wrote:
In article <11**********************@g14g2000cwa.googlegroups .com>,
"Kobu" <ko********@gmail.com> wrote:
Hi,

I've gotten into the habit of mentally converting big expressions to parse tress (started doing this after reading some c.l.c posts on parse trees).

Can someone verify if the following assumptions are correct?

1) For ++n, one can us (n=n+1) as it's equivalent:

| =
| / \
| n +
| / \
| n 1
2) For assignment operators of the form n op= b, the equivalent tree is:

| =
| / \
| n op
| / \
| n b
Correct, except that the lvalue n is only evaluated once. So

++(*++p); ++a [i++];

is absolutely not the same as

(*++p) = (*++p) + 1; a [i++] = a [i++] + 1;
but for a plain variable like n it is correct. (2) is quite important

if you need to figure out exactly what happens for example if you have a complicated case like

unsigned short us;
double d;

us += d;

In a case like that, all you need to do is to read what exactly (us + d) does, and then you read the rules what assigning a double to an unsigned short exactly does. Defining it this way must have saved dozens of pages in the C Standard.
3) For n++, one can use n, but with a side condition that (n=n+1) will occur somewhere between now and the earliest sequence point up the tree (but n=n+1 is no physically part of the tree)

|
| n
|
| [Side note: (n=n+1) can occure as a side effect anytime before the | earliest sequence point up the tree]


Yes.

Good point, I guess I can represent (exp)++ where exp has meaning as
an lvalue as:
| =
| / \
| temp +
| / \
| = 1
| / \
| temp exp <-- exp would really be more branching
| (executed once)
where (exp) = (exp) + 1 would be:

| =
| / \
| exp + <--
| / \ |-- exp related branching in two places
| exp 1 <-- (executed twice)
|

Nov 14 '05 #4

Kobu wrote:
Christian Bau wrote:
In article <11**********************@g14g2000cwa.googlegroups .com>,
"Kobu" <ko********@gmail.com> wrote:
Hi,

I've gotten into the habit of mentally converting big expressions to parse tress (started doing this after reading some c.l.c posts on parse trees).

Can someone verify if the following assumptions are correct?

1) For ++n, one can us (n=n+1) as it's equivalent:

| =
| / \
| n +
| / \
| n 1
2) For assignment operators of the form n op= b, the equivalent tree is:

| =
| / \
| n op
| / \
| n b
Correct, except that the lvalue n is only evaluated once. So

++(*++p); ++a [i++];

is absolutely not the same as

(*++p) = (*++p) + 1; a [i++] = a [i++] + 1;
but for a plain variable like n it is correct. (2) is quite

important if
you need to figure out exactly what happens for example if you have
a
complicated case like

unsigned short us;
double d;

us += d;

In a case like that, all you need to do is to read what exactly (us
+ d)
does, and then you read the rules what assigning a double to an unsigned
short exactly does. Defining it this way must have saved dozens of

pages
in the C Standard.


snip

Good point, I guess I can represent (exp)++ where exp has meaning as an lvalue as:
| =
| / \
| temp +
| / \
| = 1
| / \
| temp exp <-- exp would really be more branching
| (executed once)
where (exp) = (exp) + 1 would be:

| =
| / \
| exp + <--
| / \ |-- exp related branching in two places
| exp 1 <-- (executed twice)
|

Does this distinction apply to (exp) op= b ? Is exp guranteed to
evaluate only once or is (exp) op= b truly equivalent to (exp) = (exp)
op b ?

Nov 14 '05 #5
In article <11*********************@o13g2000cwo.googlegroups. com>,
TTroy <ti*****@gmail.com> wrote:
:Does this distinction apply to (exp) op= b ? Is exp guranteed to
:evaluate only once or is (exp) op= b truly equivalent to (exp) = (exp)
:op b ?

The C89 standard says that they are equivilent -except- that (exp)
is evaluated only once for (exp) op= b .

--
Suppose there was a test you could take that would report whether
you had Free Will or were Pre-Destined. Would you take the test?
Nov 14 '05 #6

Walter Roberson wrote:
In article <11**********************@g14g2000cwa.googlegroups .com>,
Kobu <ko********@gmail.com> wrote:

snipped

No. Suppose n is an expression that returns an lvalue and which
has side effects. In n = n + 1 then n will be evaluated for both
sides of the assignment, resulting in the side effect being done
twice. In n++ or n op= p n will only be evaluated once.

For example, queuehead()->count = queuehead()->count + 1
differs from queuehead()->count++

I've never seen that. A function name followed by the -> operator. Is
this part of C or C++? I thought -> only goes with structures.

--
When your posts are all alone / and a user's on the phone/
there's one place to check -- / Upstream!
When you're in a hurry / and propagation is a worry/
there's a place you can post -- / Upstream!


Nov 14 '05 #7
TTroy wrote:
[...]
For example, queuehead()->count = queuehead()->count + 1
differs from queuehead()->count++


I've never seen that. A function name followed by the -> operator. Is
this part of C or C++? I thought -> only goes with structures.


Hint:

extern struct MyStruct *queuehead(void);

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 14 '05 #8
In article <11*********************@z14g2000cwz.googlegroups. com>,
TTroy <ti*****@gmail.com> wrote:

:Walter Roberson wrote:
:> For example, queuehead()->count = queuehead()->count + 1

:I've never seen that. A function name followed by the -> operator. Is
:this part of C or C++? I thought -> only goes with structures.

-> goes with pointers to structures. A function can return
a pointer. In traditional C, a function could not return a structure
directly.
--
Any sufficiently advanced bug is indistinguishable from a feature.
-- Rich Kulawiec
Nov 14 '05 #9
Walter Roberson wrote:
Kobu <ko********@gmail.com> wrote:
I've gotten into the habit of mentally converting big expressions
to parse tress

Can someone verify if the following assumptions are correct?

1) For ++n, one can us (n=n+1) as it's equivalent:


No. Suppose n is an expression that returns an lvalue and which
has side effects. In n = n + 1 then n will be evaluated for both
sides of the assignment, resulting in the side effect being done
twice. In n++ or n op= p n will only be evaluated once.


That depends on the stupidity level of the code generator. For
example, for n = n+1, we might generate:

load address of n to r1
load indirect r1 to r2
add 1 to r2
(load address of n to r1) only in a STUPID code generator.
store indirect r2 via r1

n has been evaluated only once, and the expression value is in r2.
Now the n++ may be more complex, because of the need to use the
original value. The compiler may detect that this is not needed,
but...

load address of n to r1
load indirect r1 to r2
copy r2 to r3
add 1 to r2
store indirect r2 via r1

now the expression value is in r3. Of course all this depends
highly on the machine language instructions available.

Some of the important things in code generation are selecting
registers, and remembering what is in them, and when you don't
know. The more you can put off selecting, filling, and discarding
registers the better the chance of doing it efficiently by finding
out you can reuse something.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #10
In article <11**********************@f14g2000cwb.googlegroups .com>
Kobu <ko********@gmail.com> wrote:
Good point, I guess I can represent (exp)++ where exp has meaning as
an lvalue as:

| =
| / \
| temp +
| / \
| = 1
| / \
| temp exp <-- exp would really be more branching
| (executed once)
This tree is not quite right, as it never assigns a new value to
exp.
where (exp) = (exp) + 1 would be:

| =
| / \
| exp + <--
| / \ |-- exp related branching in two places
| exp 1 <-- (executed twice)
|


This tree is fine.

If you write a C compiler, you will likely discover that it is
simplest to include tree-operators for op= expressions. (You can
then use these for prefix ++ and --.) Whether you want to include
separate tree-operators for postfix ++ and -- expressions is a more
delicate matter.... (I am not sure what gcc does. By the time
it gets to code generation, however, it has gone from tree to
RTL; in the RTL, exp++ has been replaced with "tmp_reg = exp;
exp = exp + 1;" anyway. You can see this by passing the "-dr"
flag to the compiler to dump out the RTL.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #11
CBFalconer wrote:

(snip regarding ++n and n=n+1)
That depends on the stupidity level of the code generator. For
example, for n = n+1, we might generate: load address of n to r1
load indirect r1 to r2
add 1 to r2
(load address of n to r1) only in a STUPID code generator.
store indirect r2 via r1


Does volatile still exist? PL/I has ABNORMAL, which requires
the compiler to refetch from memory every time a variable is
accessed. I believe volatile was slightly different, though.

-- glen

Nov 14 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: John | last post by:
Is there an equivalent of COM on Linux that I can get through Python. My need is to have some sort of language independent component framework. I can think of CORBA but I have to have a server...
2
by: Michael Foord | last post by:
Please pardon my ignorance on this one - but I'm not certain how the sign bt is treated in python bitwise operators. I've trying to convert a javascript DES encryption routine into python. ...
3
by: Robert Dodier | last post by:
Hello, Here's a thought that I'm sure has already occurred to someone else, I just can't find any record of it yet. An XML document is just a more verbose and clumsy representation of an...
1
by: Vannela | last post by:
Is there any equivalent control in .NET for the Power builder DataWindow control? I am explaining the Datawindow architecture to some extent. Power Builder DataWindow Control has got different...
6
by: Frank Rachel | last post by:
So I can focus on the correct areas of research, I was wondering if someone could give me the .NET equivelents for this J2EE architecture: JSP's make calls to local JavaBean Controls. The...
3
by: Marty | last post by:
Hi, What is the VB.NET equivalent of the VB6 ADODB.Connector and ADODB.Recordset? Thanks Marty
7
by: Tim Conner | last post by:
Hi, I am an ex-delphi programmer, and I having a real hard time with the following simple code (example ): Which is the equivalent to the following code ? var chars : PChar; sBack, s :...
10
by: karch | last post by:
How would this C# contruct be represented in C++/CLI? Or is it even possible? PolicyLevel level = (enumerator->Current) as PolicyLevel; Thanks, Karch
9
by: Alan Silver | last post by:
Hello, I'm converting some old VB6 code to use with ASP.NET and have come unstuck with the Asc() function. This was used in the old VB6 code to convert a character to its ASCII numeric...
14
by: grid | last post by:
Hi, I have a certain situation where a particular piece of code works on a particular compiler but fails on another proprietary compiler.It seems to have been fixed but I just want to confirm if...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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,...

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.