473,445 Members | 1,880 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

++i vs i++

asm
Hi All,

I would like to know when ++i should be used instead of i++ and vice versa.
Some code examples would be of help.

Does it really matter for assignments?

Thanks,
Arut
Nov 14 '05
59 27325
Richard Bos wrote:
If you prefer, here are some alternate translations:
Original:
while(*++p) { ... }
With comma:
while(p++, *p) { ... }
Duplicating increment:
p++;
while(*p) { ...; p++; }


Congratulations. You've just turned a perfectly good, completely
understandable while loop into a rather more complicated and somewhat
less maintainable one, which may under unusual circumstances not even be
completely equivalent.


I certainly wouldn't prefer that particular translation, because it is
less maintainable (code duplication) and separates the increment from
the condition. I was simply listing alternatives. I actually like the
one using array indexing the most, because it makes it easier to reason
about out-of-bounds conditions and resembles your average linear scan
with a for loop through an array.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #51
Derrick Coetzee <dc****@moonflare.com> wrote:
Richard Bos wrote:
_Transmitted_ across a string of tokens? Whatever do you mean by that?


I refer to the distance the token would have to be moved in order for
the lexical order to reflect the execution order.


Hum. Does the term "sequence point" mean anything to you? What makes you
think that there even _is_ a fixed execution order which would make this
move necessary?

Richard
Nov 14 '05 #52
Derrick Coetzee <dc****@moonflare.com> wrote in message news:<cj**********@news-int.gatech.edu>...
Method Man wrote:
It's all subjective to who the code's audience is. To experienced
programmers, operators like '++' become second nature.
Keep in mind that not every programmer who maintains your code may be an
expert, or be an expert who is particular lucid at the time (under high
stress, low on sleep, hangover, etc.) To experienced programmers,
assembly language is second nature, but that doesn't mean we prefer it.


Anyone programming in C or C++ for a living learns how ++ and -- work,
and rather quickly. Statements like 'while (*p++) {...}' are
perfectly idiomatic C, which any sufficiently
brain-dam^H^H^H^H^H^H^H^H^H competent code monkey should be able to
understand.

Seriously, this isn't *that* difficult a concept to grasp.
And consider:
(*p). vs p->
Which is more readable and which is used more often?


The important thing is that lexical order reflects execution order.


Since when? Given the expression

a() + b() * c()

is there any guarantee that a() is executed before b() or c()? Should
there be?
In this case you can read "p->" as a single conceptual operation with
chooses a member from the object p refers to. The choice of * as a
prefix rather than a postfix operator is arbitrary (although in this
case needed to automatically parse things correctly). This is
effectively a local transformation, unlike ++, which can potentially be
transmitted across an arbitrarily long string of tokens, as in this example:

b = a++ + /* one-million token expression */;


'a++' evaluates to the value of 'a'; that value is applied immediately
as part of the expression (i.e., lexical order reflects execution
order). The *side effect* may be applied immediately, or it may be
deferred to the next sequence point. As far as assigning to b is
concerned, it simply doesn't matter. You just have to make sure that
the token 'a' doesn't appear again before the next sequence point.
Nov 14 '05 #53

"Michael Wojcik" <mw*****@newsguy.com> wrote
Your example shows UB when sp equals STACK_SIZE -1. As I said,
use of pre-increment can be confusing.
Non sequitur. The code displays the same UB without use of the
pre-increment operator (that is, if another increment expression,
such as the one John suggested in the comments, were substituted
for it), and nothing you've posted shows that the pre-increment
operator disguised that fact in any way.

Evidence isn't proof. The fact that a bug appeared in a small fragment
showing use of the pre-increment operator is evidence that using such an
operator caused the problem. However programmers make errors all of the
time. Maybe John Bode had drunk one too many beers before posting, and that
was the reason for the mistake. My own view is that use of pre-increment was
a contributing factor
Also, your argument hinges on your contention that stack be declared:
int stack[STACK_SIZE];


while it might just as easily have been declared:
int stack[STACK_SIZE+1];


The latter form - where a manifest constant for "array size" actually
refers to the largest valid index - is not uncommon in C source.

This is error masking. Some function deep in the gubbins of the program
overflows the stack by one. So instead of getting to the root of the problem
we increment the stack size by one and hope the bug goes away. Often it
works. Other times it piles bug on bug.
STACK_SIZE should be the size of the stack - i.e. the maximum number of
items it can hold. Anything else is sowing confusion.
Nov 14 '05 #54

"Michael Wojcik" <mw*****@newsguy.com> wrote

Confusion for whom? You seem to be a member of a rather small
minority - just you, perhaps - which finds it confusing. Or do you
have some empirical data to demonstrate otherwise?

See elsethread for an example of a bug introduced into example code
supposedly showing how to use the prefix increment operator.
Nov 14 '05 #55
jo*******@my-deja.com (John Bode) wrote:
Derrick Coetzee <dc****@moonflare.com> wrote in message news:<cj**********@news-int.gatech.edu>...
b = a++ + /* one-million token expression */;


'a++' evaluates to the value of 'a'; that value is applied immediately
as part of the expression (i.e., lexical order reflects execution
order). The *side effect* may be applied immediately, or it may be
deferred to the next sequence point. As far as assigning to b is
concerned, it simply doesn't matter. You just have to make sure that
the token 'a' doesn't appear again before the next sequence point.


Not quite. You have to make sure that the _object_ a doesn't appear
again before the next sequence point. If there's a pointer to a, you
can't dereference it in the one million tokens.

Richard
Nov 14 '05 #56
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote in message news:<cj**********@news8.svr.pol.co.uk>...
"Michael Wojcik" <mw*****@newsguy.com> wrote
Your example shows UB when sp equals STACK_SIZE -1. As I said,
use of pre-increment can be confusing.
Non sequitur. The code displays the same UB without use of the
pre-increment operator (that is, if another increment expression,
such as the one John suggested in the comments, were substituted
for it), and nothing you've posted shows that the pre-increment
operator disguised that fact in any way.

Evidence isn't proof. The fact that a bug appeared in a small fragment
showing use of the pre-increment operator is evidence that using such an
operator caused the problem.


Didn't you just say that evidence isn't proof?

This is priceless. The bug had dick all to do with the preincrement
operator; like Michael pointed out, the same UB would have shown up if
I hadn't used the preincrement. The root cause of the bug is that C
arrays are 0-origin (and that I wasn't paying close enough attention).
However programmers make errors all of the time.
Hence why we have QA and maintenance programmers.
Maybe John Bode had drunk one too many beers before posting, and that
was the reason for the mistake.
Oh, would that were true...mmmm, beer...dammit, now I'm thirsty...
My own view is that use of pre-increment was a contributing factor
My view is that a 0-origin array was the primary factor.

Also, your argument hinges on your contention that stack be declared:
int stack[STACK_SIZE];


while it might just as easily have been declared:
int stack[STACK_SIZE+1];


The latter form - where a manifest constant for "array size" actually
refers to the largest valid index - is not uncommon in C source.

This is error masking.


No, it isn't merely "error masking".
Some function deep in the gubbins of the program
overflows the stack by one.
Not if you design your API correctly.
So instead of getting to the root of the problem
we increment the stack size by one and hope the bug goes away. Often it
works. Other times it piles bug on bug.
STACK_SIZE should be the size of the stack - i.e. the maximum number of
items it can hold. Anything else is sowing confusion.


The maximum stack size is a *logical* entity; there's no reason why
the physical implementation has to be the same size. In fact, the way
I wrote it, the array *has* to be STACK_SIZE+1 elements to hold
STACK_SIZE items, because element 0 is never written to.
Nov 14 '05 #57

"John Bode" <jo*******@my-deja.com> wrote

Didn't you just say that evidence isn't proof?

This is priceless. The bug had dick all to do with the preincrement
operator; like Michael pointed out, the same UB would have shown up if
I hadn't used the preincrement. The root cause of the bug is that C
arrays are 0-origin (and that I wasn't paying close enough attention).
Here's the code

added by Malcolm

int stack[STACK_SIZE];
int sp;
if (sp < STACK_SIZE)
{
/*
** The following statement replaces these two statements
**
** sp = sp + 1;
** stack[sp] = value;
*/
stack[++sp] = value;
}
else
{
/* handle overflow */
}
Seems to me quite clearly that the pre-increment is contributing to the
problem. On entry, sp < STACK_SIZE, so writing "stack[sp++] = value;" would
give you the right behaviour, at the price of making sp no longer pointing
to stack top but to the empty space above it.
However programmers make errors all of the time.

However we all make mistakes, so to conclude that pre-increment is confusing
on the basis of one bug is a bit premature. To conclude that it is not
confusing (evidence isn't proof, therefore evidence that falls short of
proof is evidence against) is a fallacy.
The maximum stack size is a *logical* entity; there's no reason why
the physical implementation has to be the same size. In fact, the way
I wrote it, the array *has* to be STACK_SIZE+1 elements to hold
STACK_SIZE items, because element 0 is never written to.

You're in good company here. No less than the authors of "Numerical Recipies
in C" endorse 1-based arrays. Mathematicians count 1, 2, 3 ..., computers
count 0, 1, 2 ... . However the consensus is that 1-based arrays in C are a
bad idea.
Nov 14 '05 #58
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote in message news:<cj**********@newsg4.svr.pol.co.uk>...
"John Bode" <jo*******@my-deja.com> wrote

Didn't you just say that evidence isn't proof?

This is priceless. The bug had dick all to do with the preincrement
operator; like Michael pointed out, the same UB would have shown up if
I hadn't used the preincrement. The root cause of the bug is that C
arrays are 0-origin (and that I wasn't paying close enough attention).
Here's the code

added by Malcolm

int stack[STACK_SIZE];
int sp;
if (sp < STACK_SIZE)
{
/*
** The following statement replaces these two statements
**
** sp = sp + 1;
** stack[sp] = value;
*/
stack[++sp] = value;
}
else
{
/* handle overflow */
}

Seems to me quite clearly that the pre-increment is contributing to the
problem.


What if I had written

if (sp < STACK_SIZE)
{
sp = sp + 1;
stack[sp] = value;
}

The pre-increment operator is nowhere in sight, yet the bug is still
there. It seems to me that the problem is in the test (actually, the
problem's in the overall logic; more on that below).
On entry, sp < STACK_SIZE, so writing "stack[sp++] = value;" would
give you the right behaviour, at the price of making sp no longer pointing
to stack top but to the empty space above it.


Which is not what I want sp to do. I want sp to point to the last
thing pushed onto the stack, not the next available slot.

Actually, now that I've thought about it, the *right* solution is to
grow from the top down:

static int sp = STACK_SIZE;

void push (int value)
{
if (sp > 0)
stack[--sp] = value;
else
/* overflow */
}

int pop (void)
{
if (sp < STACK_SIZE)
return stack[sp++];
else
/* underflow */
}

A little cleaner, and all array elements actually get used. Like I
said, I tossed off the original example while waiting for something
else to finish and didn't verify it properly. Bad me. No cookie.
However programmers make errors all of the time.

However we all make mistakes, so to conclude that pre-increment is confusing
on the basis of one bug is a bit premature. To conclude that it is not
confusing (evidence isn't proof, therefore evidence that falls short of
proof is evidence against) is a fallacy.

The maximum stack size is a *logical* entity; there's no reason why
the physical implementation has to be the same size. In fact, the way
I wrote it, the array *has* to be STACK_SIZE+1 elements to hold
STACK_SIZE items, because element 0 is never written to.

You're in good company here. No less than the authors of "Numerical Recipies
in C" endorse 1-based arrays. Mathematicians count 1, 2, 3 ..., computers
count 0, 1, 2 ... . However the consensus is that 1-based arrays in C are a
bad idea.


I don't *endorse* the idea of 1-based arrays in C. I was merely
pointing out that the bug in my code was due to not taking 0-origin
arrays into account, not because I used a preincrement operator.
Since the bug still exists if I replace the preincrement with a
separate increment statement, I'd say my point is valid.

And my *actual* point was that the physical and logical
representations of a stack didn't have to map exactly.
Nov 14 '05 #59
On 27 Sep 2004 20:17:24 GMT, ri*****@cogsci.ed.ac.uk (Richard Tobin)
wrote:
<snip>
For stack-like applications, post-increment goes naturally with
pre-decrement and vice versa. Having used PDP-11 assembler a few
decades ago, I generally write i++ and --i when there is no other
reason to prefer one to the other.

For downward-growing stacks as introduced on the -11 and now seemingly
universal. Some other machines, (most?) notably PDP-10, had upward
stacks which of course prefer preinc and postdec.
- David.Thompson1 at worldnet.att.net
Nov 14 '05 #60

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

Similar topics

3
by: William C. White | last post by:
Does anyone know of a way to use PHP /w Authorize.net AIM without using cURL? Our website is hosted on a shared drive and the webhost company doesn't installed additional software (such as cURL)...
2
by: Albert Ahtenberg | last post by:
Hello, I don't know if it is only me but I was sure that header("Location:url") redirects the browser instantly to URL, or at least stops the execution of the code. But appearantely it continues...
3
by: James | last post by:
Hi, I have a form with 2 fields. 'A' 'B' The user completes one of the fields and the form is submitted. On the results page I want to run a query, but this will change subject to which...
0
by: Ollivier Robert | last post by:
Hello, I'm trying to link PHP with Oracle 9.2.0/OCI8 with gcc 3.2.3 on a Solaris9 system. The link succeeds but everytime I try to run php, I get a SEGV from inside the libcnltsh.so library. ...
1
by: Richard Galli | last post by:
I want viewers to compare state laws on a single subject. Imagine a three-column table with a drop-down box on the top. A viewer selects a state from the list, and that state's text fills the...
4
by: Albert Ahtenberg | last post by:
Hello, I have two questions. 1. When the user presses the back button and returns to a form he filled the form is reseted. How do I leave there the values he inserted? 2. When the...
1
by: inderjit S Gabrie | last post by:
Hi all Here is the scenerio ...is it possibly to do this... i am getting valid course dates output on to a web which i have designed ....all is okay so far , look at the following web url ...
2
by: Jack | last post by:
Hi All, What is the PHP equivilent of Oracle bind variables in a SQL statement, e.g. select x from y where z=:parameter Which in asp/jsp would be followed by some statements to bind a value...
3
by: Sandwick | last post by:
I am trying to change the size of a drawing so they are all 3x3. the script below is what i was trying to use to cut it in half ... I get errors. I can display the normal picture but not the...
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
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
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,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
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...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...

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.