Poll

What's your local practice?

for(i=0; i < count; i++)
24 (75%)
for(i=0; i < count; ++i)
8 (25%)

Total Members Voted: 32

Voting closed: October 11, 2020, 10:10:24 pm

Author Topic: Prefix or postfix increment in 'for' loops  (Read 7865 times)

0 Members and 1 Guest are viewing this topic.

Offline hamster_nzTopic starter

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Prefix or postfix increment in 'for' loops
« on: October 08, 2020, 10:10:24 pm »
I've seen both, they are identical and just wondering what you use and why.

Me? I tend to avoid prefixed increment, I guess I just to want it the variable to be on the left hand side...
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline AntiProtonBoy

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: au
  • I think I passed the Voight-Kampff test.
Re: Prefix or postfix increment in 'for' loops
« Reply #1 on: October 08, 2020, 11:05:30 pm »
they are identical
Not always:

Code: [Select]
int i = 5;
int a = ++i;
int b = i++;
assert( a != b );

In C++, there could be also performance implications if you overload the aforementioned operators for your classes. If your class is big, the prefix operator requires only a reference to the object to be returned, whereas the postfix version must return a temporary object by value.
 

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3389
  • Country: nl
Re: Prefix or postfix increment in 'for' loops
« Reply #2 on: October 08, 2020, 11:39:18 pm »
Use whatever is works for you.
One of my favorites is:

Code: [Select]
for ( uint8_t Mask = 1; Mask; Mask <<=1){ ...}
also compare these:

Code: [Select]
int func_a( void) {
    int Num = 42;
   
    return ++Num;
//    return Num++;    // Now try this for a change...
}

... which is a variant of the same of antiprotonboy's post.
And another hint, If they were the same, they would not both be defined in C.
The difference can be particularly usefull when indexing through arrays.
« Last Edit: October 08, 2020, 11:42:39 pm by Doctorandus_P »
 

Offline Cerebus

  • Super Contributor
  • ***
  • Posts: 10576
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #3 on: October 08, 2020, 11:57:56 pm »
they are identical
Not always:

Code: [Select]
int i = 5;
int a = ++i;
int b = i++;
assert( a != b );

In C++, there could be also performance implications if you overload the aforementioned operators for your classes. If your class is big, the prefix operator requires only a reference to the object to be returned, whereas the postfix version must return a temporary object by value.

I think the 'they' there referred to the whole loops, not to the operators which clearly deliver different result values. The loops are functionally identical whichever you use, pre- or post- increment, as the returned value from the increment operation is discarded.
Anybody got a syringe I can use to squeeze the magic smoke back into this?
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14564
  • Country: fr
Re: Prefix or postfix increment in 'for' loops
« Reply #4 on: October 09, 2020, 12:17:17 am »
they are identical
Not always:

Code: [Select]
int i = 5;
int a = ++i;
int b = i++;
assert( a != b );

In C++, there could be also performance implications if you overload the aforementioned operators for your classes. If your class is big, the prefix operator requires only a reference to the object to be returned, whereas the postfix version must return a temporary object by value.

I think the 'they' there referred to the whole loops, not to the operators which clearly deliver different result values. The loops are functionally identical whichever you use, pre- or post- increment, as the returned value from the increment operation is discarded.

Of course. The question was strictly limited to this use case in the original post. I'm sure hamster knows the difference when you *use* the value of a pre- or post-incremented expression. But it's very common in those threads to get off-topic very quickly.

Now even if you don't use the value itself, could this make a difference? Certainly not in C, but I guess in some object-oriented languages, if the variable is actually an object and the language allows defining operators for objects, then certainly the result *could* be different, although defining them differently (as far as the side-effect goes, which is incrementing the "value" in some way, so apart again from the return value) would probably not make any sense.

Back to what the original question most likely was: yes I've seen both forms in the final clause of for loops in C. I personally use the former, as it looks more natural, and thus more readable IMO.
I remember having heard of a rationale from people using the '++i' form *in this context* (so again with the value itself discarded, just saying it again but making sure no one will be again tempted to reply with examples in which the value of the expression is used), but it was probably so smart and so relevant that I don't even remember it. ;D

And say, even in C++, if the variable is of an integer (or pointer) type, which is most likely what the OP was thinking of, there is absolutely no difference.
 

Offline maginnovision

  • Super Contributor
  • ***
  • Posts: 1963
  • Country: us
Re: Prefix or postfix increment in 'for' loops
« Reply #5 on: October 09, 2020, 01:28:40 am »
I do not have strong feelings either way so I checked my code. I do prefix.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 3447
  • Country: us
Re: Prefix or postfix increment in 'for' loops
« Reply #6 on: October 09, 2020, 01:53:33 am »
I formed my habit of using "++i" instead of "i++" -- from older (and smaller code-size) compilers without good optimization.

++i means increment first then use the value, so ++i typical leaves the new value in register and ready to be use by the loop-condition test, whereas i++ leaves the old value (use old value then increment) in register and requires another memory read.

Of course, compilers have much better optimization now.  But my habit is already form.  So it is purely fossilized habit that I continue to favor ++i over i++.  Besides, it makes sense to me - I am using the value in the condition-test after the increment.

« Last Edit: October 09, 2020, 01:55:42 am by Rick Law »
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21741
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Prefix or postfix increment in 'for' loops
« Reply #7 on: October 09, 2020, 02:11:45 am »
I use postfix, largely by habit.

On a related subject, it's preferred to put constants on the left-hand side of a conditional: this errors out if you typo an equality in. "if (7 == x)" is correct, "if (7 = x)" errors, "if (x = 7)" works silently and not as you might've expected it to!  (Modern compilers do warn of assignment-in-conditional; but sometimes it is intended as well.)  I tend...not to do this, again largely by habit. ::) (Fortunately, I'm no SW dev, so I can afford to make mistakes in my own projects.)

Tim
« Last Edit: October 09, 2020, 02:13:18 am by T3sl4co1l »
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3053
  • Country: us
Re: Prefix or postfix increment in 'for' loops
« Reply #8 on: October 09, 2020, 02:14:42 am »
The Google C++ Style Guide says:

Quote
Pros:

A postfix increment/decrement expression evaluates to the value as it was before it was modified. This can result in code that is more compact but harder to read. The prefix form is generally more readable, is never less efficient, and can be more efficient because it doesn't need to make a copy of the value as it was before the operation.

Cons:

The tradition developed, in C, of using post-increment, even when the expression value is not used, especially in for loops. Some find post-increment easier to read, since the "subject" (i) precedes the "verb" (++), just like in English.

Decision:

Use prefix increment/decrement, unless the code explicitly needs the result of the postfix increment/decrement expression.

https://google.github.io/styleguide/cppguide.html#Preincrement_and_Predecrement

Note that if you are using C++ and define iterator semantics for a type I think you'll always want to use pre-increment because the compiler might not be able to optimize away unnecessary increment operations. For that reason I would get in the habit of using pre-increment.
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6808
  • Country: pl
Re: Prefix or postfix increment in 'for' loops
« Reply #9 on: October 09, 2020, 07:17:44 am »
On a related subject, it's preferred to put constants on the left-hand side of a conditional: this errors out if you typo an equality in. "if (7 == x)" is correct, "if (7 = x)" errors, "if (x = 7)" works silently and not as you might've expected it to!  (Modern compilers do warn of assignment-in-conditional; but sometimes it is intended as well.)  I tend...not to do this, again largely by habit. ::) (Fortunately, I'm no SW dev, so I can afford to make mistakes in my own projects.)
It's rare, thankfully :phew:
Basically, a nonissue that autists obssess about :P
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3788
  • Country: de
Re: Prefix or postfix increment in 'for' loops
« Reply #10 on: October 09, 2020, 08:20:47 am »
The main reason why prefix is used and recommended in situations where everything else would be equal (i.e. you don't specifically care about the order of operations), is that postfix will make a temporary copy of the value.

Probably not much of an issue in C with something like an integer and a good compiler that will optimize the temporary out but it could be pretty bad if you use that operator in C++ on something that is not a simple data type. C++ allows operator overloading and making a copy of a large class/struct, especially in a loop like this, is going to be terribly inefficient.

 

Offline NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 2495
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #11 on: October 09, 2020, 09:21:40 am »
There needs to be a third option on the poll.

Seriously modern compilers are really really smart so this is a non question

If you want some reading try https://www.drdobbs.com/architecture-and-design/efficiency-versus-intent/228700184
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6808
  • Country: pl
Re: Prefix or postfix increment in 'for' loops
« Reply #12 on: October 09, 2020, 09:31:58 am »
Yes indeed.

I'm not quite old enough to remember it personally, but I always assumed that this practice was popularized by the C++ crowd when iterators were introduced. Those, being fully featured classes with methods and stuff, make postincrement somewhat harder to optimize than with basic types.

C programmers generally don't bother. And heck, even C++ is called C++ rather than ++C, despite the value of the former expression still technically being just C ;D
« Last Edit: October 09, 2020, 09:44:22 am by magic »
 
The following users thanked this post: NivagSwerdna

Offline PKTKS

  • Super Contributor
  • ***
  • Posts: 1766
  • Country: br
Re: Prefix or postfix increment in 'for' loops
« Reply #13 on: October 09, 2020, 11:53:11 am »

Las two comments HOLD TRUE.

Today this is no longer even for consideration.

*UNLESS* obviously you are compiling code using older
things like Borland 3,4/5 or even 6 or even the watcom (modern
openwatcom as well)..

With the advent of  full register renaming re-indexing and
FULL RISC opcode micro firmware it is mostly a waste of time
thinking *what* a modern compiler (say GCC >=9.x) would do
inside the loops.

Ancient alternative were using options line "unroll-loops" and
optimization specific target the CPU ... but these alternatives
only serves to generate UNPORTABLE CODE among modern CPUs.

I always keep it safe using i++  and letting the compiler optimizer
do the less risky thing .. as the full loop may be interrupted in modern threads.

hard to guess.

Paul
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3788
  • Country: de
Re: Prefix or postfix increment in 'for' loops
« Reply #14 on: October 09, 2020, 02:06:45 pm »
Guys, if you are talking about compilers and optimizations, you are making some very big assumptions.

Are we dealing with C and/or iterating POD (plain old data) types? Possibly - in that case sure, be my guest. In C and with integral types the cost of the extra copy is going to be negligible and a modern compiler will most likely notice you aren't using the value for anything and optimize the temporary out.

However, once you are in C++ (and the OP did not specify which language is it for!) and are dealing e.g. with iterators or containers that define these operators (both are commonly used in for loops), you can't rely on the compiler optimization to save your bacon!

There is a reason why a large part of the C++ standard deals with things like references, move semantic, universal references - all that is to avoid copying large data structures which could end up being pretty expensive. If this was so easy for compilers to optimize out there would be no need for all that complexity.

« Last Edit: October 09, 2020, 02:09:48 pm by janoc »
 

Offline PKTKS

  • Super Contributor
  • ***
  • Posts: 1766
  • Country: br
Re: Prefix or postfix increment in 'for' loops
« Reply #15 on: October 09, 2020, 02:38:35 pm »
Not much of an issue.

C++ is C with classes.

Unless you will NOT USE at all C constructs  just
plain templates or overloaded classes...

You will do a regular C "for" construct in both.

Notable exception in above comment is that ME and
probably several other old school die hard bad habits
of direct memory address are really  a nasty problem

EXAMPLE:

some_lvalue  = & some_pointer( ++dma )

WTF is not under case like
some_lvalue  = & some_pointer( dma++ )

or variants to auto increment indexed pointers:
auto_addr = ++ * some_pointer( dma )

WTF not even close to
auto_addr = * some_pointer( dma ) ++

I am used to write these and mostly I translate
that shit to ASM to avoid MODERN CRAPPY MULTI-CPU issues

in small words:
you need to make dead sure the pointer will access
location prior or post the indexed increment takes place
and letting just the C operator precedence will lead this
code in issues when interrupted in sensitive contexts.


Paul
« Last Edit: October 09, 2020, 02:49:07 pm by PKTKS »
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5320
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #16 on: October 09, 2020, 03:43:51 pm »
Personally by habit I've used i++ for decades as my go to option.

And my goto option is irrelevant, I've never once used goto in C.

 

Offline NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 2495
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #17 on: October 09, 2020, 03:51:32 pm »
Goodness.. this one is going to run and run...

Here's an interesting take...

https://google.github.io/styleguide/cppguide.html#Preincrement_and_Predecrement

Basically it's us old school traditionalists that insist on using post increment... we're just dinosaurs.

Obviously either works and the LVAR is thrown away when the operation is invoked so pre and post are indistinguishable functionally here.

TGIF
 

Offline maginnovision

  • Super Contributor
  • ***
  • Posts: 1963
  • Country: us
Re: Prefix or postfix increment in 'for' loops
« Reply #18 on: October 09, 2020, 04:40:54 pm »
Personally by habit I've used i++ for decades as my go to option.

And my goto option is irrelevant, I've never once used goto in C.

I looked at my first c game I wrote when I was 11 or so. It was a single main function full of labels and gotos. I thought it was funny and showed it to some people to try and follow it.
« Last Edit: October 09, 2020, 04:43:38 pm by maginnovision »
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3788
  • Country: de
Re: Prefix or postfix increment in 'for' loops
« Reply #19 on: October 09, 2020, 05:00:37 pm »
Not much of an issue.

C++ is C with classes.

:palm:

Sorry, I guess you haven't written much C++ (not C compiled with a C++ compiler) code, have you?



Unless you will NOT USE at all C constructs  just
plain templates or overloaded classes...

You will do a regular C "for" construct in both.


That's just a tautology. Aka "If you write C code in C++ you will be writing regular C for".


in small words:
you need to make dead sure the pointer will access
location prior or post the indexed increment takes place
and letting just the C operator precedence will lead this
code in issues when interrupted in sensitive contexts.

That's just plain bad code that wouldn't pass a code review, full stop. Taking addresses of temporaries by chance? And I feel you are conflating several unrelated issues there too, given your comment on "MODERN CRAPPY MULTI-CPU issues".

Whether you are using prefix or postfix increment has no bearing on any "multi-CPU issues" unless you are grossly ignoring basic concurrency issues like not sharing state between two threads (or an interrupt handler and some other code) without synchronization. But that is just poor code, nothing else.

 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6808
  • Country: pl
Re: Prefix or postfix increment in 'for' loops
« Reply #20 on: October 09, 2020, 05:43:02 pm »
However, once you are in C++ (and the OP did not specify which language is it for!) and are dealing e.g. with iterators or containers that define these operators (both are commonly used in for loops), you can't rely on the compiler optimization to save your bacon!
It kinda depends on how complex the iterator is. I have a (never verified) suspicion that in STL containers most iterators consist of just a pointer to the given element or null. In some calling conventions (like x86-64 Linux) returning by value a structure of up to two 64 bit words from a class method or other function goes through registers RAX, RDX and is essentially free. But on 32 bit Linux it was never like that and no idea about other systems like Windows.

And if the operator++ method is sufficiently trivial (think: list iterator) it will very likely get inlined and then elimination of an unused temporary is a trivial optimization that any modern C++ compiler will do at non-zero optimization level.

But you are making a gamble relying on any of that unless you know what you are doing and writing a strictly platform-specific code.
« Last Edit: October 09, 2020, 05:45:08 pm by magic »
 

Online S. Petrukhin

  • Super Contributor
  • ***
  • Posts: 1199
  • Country: ru
Re: Prefix or postfix increment in 'for' loops
« Reply #21 on: October 09, 2020, 08:00:34 pm »
for i:=1 to 10 do begin

end;

 :popcorn:
And sorry for my English.
 
The following users thanked this post: T3sl4co1l, Howardlong

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5320
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #22 on: October 09, 2020, 09:48:35 pm »
for i:=1 to 10 do begin

end;

 :popcorn:

Crikey, that takes me back, I earned a crust writing that stuff back in the mid 80s. Pascal on a Pr1me, then Turbo Pascal and Microsoft Pascal on the PC. I was quite the fan boy of Pascal. Turbo Pascal, with its IDE and super fast in-memory edit-compile-run paradigm was a massive turning point in programming development, it showed what could be done, and Microsoft took a long time to catch up.

I remember Microsoft coming out with Programmer's Workbench (PWB), possibly the biggest single hinderance to software development there ever was. a huge bloated disk intensive monstrosity that tried to cover all bases, something that it did indeed achieve, just really, really badly.

We used to do unit testing in Turbo C because it was much faster (we made our source code compatible between compilers to aid development time), and then system test & beyond was in in Microsoft C.
 

Offline indeterminatus

  • Contributor
  • Posts: 30
  • Country: at
Re: Prefix or postfix increment in 'for' loops
« Reply #23 on: October 09, 2020, 10:19:39 pm »
My take on this (as SW engineer): consistency. Pick one and stick with it, at least within a given project. Do not pay too much attention to "potential performance problems" with either one of them. If that really is your biggest concern, you've already done an extra-ordinarily good job. Most of the times, the increment of a loop variable will make no difference.

As far as performance optimization goes: always measure, never guess. Do not optimize prematurely, it may even have an adverse effect (you'd be surprised how smart compilers actually can be!). Optimize on macroscopic level (pick appropriate algorithms and data structures), taking the boundary conditions into account; bubble sort, while scaling terribly, might actually be fast enough if you know you're only ever dealing with a hand-ful of elements. Profile, profile, profile. And then profile some more. Pick the hotspots and remove them. Then profile again to verify improvements.

More often than not, the clarity of the code should be your number 1 priority. It should be immediately obvious what the code is doing and why. When reading the code, the moment you have to stop and think what the hell is going on, its structure is bad and needs to be changed. Never waste the time of the person reading your code -- this is very rude. Which closes the loop: consistency. If you use post-increment here and here and here, and at one place you pre-increment, what you're basically doing is forcing the reader of the code to think about the difference and why that would be important. Time and concentration budget that could've been spent more productively, going to waste.

This may sound a bit harsh, but I've seen many programs written by brilliant mathematicians and physicists, that are a nightmare to read and understand, let alone adapt. If you think about it, the "adapting" part is the main trait of the software. If it cannot be easily changed, it is no longer "soft", and thus misses its point. Please, don't be clever.
 
The following users thanked this post: Howardlong

Offline indeterminatus

  • Contributor
  • Posts: 30
  • Country: at
Re: Prefix or postfix increment in 'for' loops
« Reply #24 on: October 10, 2020, 08:57:03 am »
I am not offering any of my code for anyone hete  to review

in particular to satisfy bad egos envy and child like fooly insults

In case you're referring to my reply, no insult was intended, and I do most certainly not want to discourage exposing yourself to criticism. It takes a lot of courage to post bits of work; it's easy to criticize, it's very difficult to create something. This is an unfair bias that (unfortunately) often leaves a bitter taste after review.
 

Offline PKTKS

  • Super Contributor
  • ***
  • Posts: 1766
  • Country: br
Re: Prefix or postfix increment in 'for' loops
« Reply #25 on: October 10, 2020, 09:50:17 am »

(no shit)

That's just plain bad code that wouldn't pass a code review, full stop.

(no shit)

2 cents ...

I am not offering any of my code for anyone here  to review

in particular to satisfy bad egos envy and child like folly insults

That folk probably thinks he is that full of shit
Paul
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6327
  • Country: fi
    • My home page and email address
Re: Prefix or postfix increment in 'for' loops
« Reply #26 on: October 10, 2020, 08:25:48 pm »
for (i = 0; i < count; i += 1)
 

Online S. Petrukhin

  • Super Contributor
  • ***
  • Posts: 1199
  • Country: ru
Re: Prefix or postfix increment in 'for' loops
« Reply #27 on: October 10, 2020, 09:21:38 pm »
for (i = 0; i < count; i += 1)
for (i=0; i<count; i=i+1)
And sorry for my English.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6327
  • Country: fi
    • My home page and email address
Re: Prefix or postfix increment in 'for' loops
« Reply #28 on: October 10, 2020, 10:55:16 pm »
Actually, for (double d = dmin; d <= dmax; d = nextafter(d, HUGE_VAL)) is occasionally useful (in C99 or later) to examine all double values between dmin and dmax, inclusive.  It's also one of the examples where using a floating-point loop variable is perfectly acceptable.
 

Online S. Petrukhin

  • Super Contributor
  • ***
  • Posts: 1199
  • Country: ru
Re: Prefix or postfix increment in 'for' loops
« Reply #29 on: October 11, 2020, 12:27:07 am »
Actually, for (double d = dmin; d <= dmax; d = nextafter(d, HUGE_VAL)) is occasionally useful (in C99 or later) to examine all double values between dmin and dmax, inclusive.  It's also one of the examples where using a floating-point loop variable is perfectly acceptable.

The for loop in all languages is iterative, i.e. it repeats by counter. The C language historically did not have this loop, and with all its inherent perversity, this macro was muddied, essentially writing the while loop in one line.  :-//
And sorry for my English.
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4054
  • Country: nz
Re: Prefix or postfix increment in 'for' loops
« Reply #30 on: October 11, 2020, 12:28:43 am »
Actually, for (double d = dmin; d <= dmax; d = nextafter(d, HUGE_VAL)) is occasionally useful (in C99 or later) to examine all double values between dmin and dmax, inclusive.  It's also one of the examples where using a floating-point loop variable is perfectly acceptable.

With IEEE FP you can do this with just an integer loop and ++i and bit cast the integer to FP, as long as you're not trying to iterate between a negative number and a positive number (or the reverse).
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6327
  • Country: fi
    • My home page and email address
Re: Prefix or postfix increment in 'for' loops
« Reply #31 on: October 11, 2020, 05:20:34 am »
Yep; in fact, if integer and floating point byte orders are the same, IEEE Binary32 and Binary64 floating-point types data interpreted as an integer will have the same order as the values, if one inverts the sign bit when the sign bit is clear, and all bits when the sign bit is set.  (Darn, I always get that wrong the first time.)  This is useful for implementing floating-point radix sort for huge data sets, so you can sort those in linear time – although the constant time factor is so large Quicksort et al. will be faster unless you have tens or hundreds of millions of elements or more; depends a bit on the radix sort implementation (bits per pass) and CPU core cache behaviour.
« Last Edit: October 11, 2020, 05:28:45 am by Nominal Animal »
 

Offline Syntax Error

  • Frequent Contributor
  • **
  • Posts: 584
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #32 on: October 11, 2020, 08:47:50 pm »
Loops, I most often use for ( i = 0; i < count; i++ ), unless it's a zero indexed array when obviously...
Code: [Select]
for ( i = 0; i < array.count - 1; i++ )Except darn LUA where arrays index from 1, go figure?

But is the OP's loop functionally the same as these code snippets (your I.T.L. homework question btw)...
Code: [Select]
i = 0
repeat { i++; // stuff...; } until ( i < count )
i = 0
repeat { // stuff...; } until ( ++i < count )

A moot point when...
Code: [Select]
FOR i = 0 TO count STEP 1
NEXT i

Just one thought to really upset the interpreter nerds though...
Code: [Select]
FOR i = 0 TO count STEP 0.000000000000000000000000001
NEXT i

Now hop backwards, just for fun...
Code: [Select]
for ( uint32_t i = count; i != -1 ; --i )* Noobs, can you spot the syntax error here?

Or just geek out with...
Code: [Select]
i = -1; while ( ( ++i < count ) ? true : false ; ) { // stuff... }
Yeh, it's like this yawl |O
« Last Edit: October 12, 2020, 08:45:38 am by Syntax Error »
 

Offline AntiProtonBoy

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: au
  • I think I passed the Voight-Kampff test.
Re: Prefix or postfix increment in 'for' loops
« Reply #33 on: October 11, 2020, 11:37:42 pm »
Not much of an issue.

C++ is C with classes.
Disagree. They are distinct languages and should not be conflated in any way. The C++ should be treated as a unique language that in a sense offers a C compatibility layer in syntax and in the ABI.

Quote
some_lvalue  = & some_pointer( ++dma )

WTF is not under case like
some_lvalue  = & some_pointer( dma++ )

or variants to auto increment indexed pointers:
auto_addr = ++ * some_pointer( dma )

WTF not even close to
auto_addr = * some_pointer( dma ) ++

I am used to write these and mostly I translate
that shit to ASM to avoid MODERN CRAPPY MULTI-CPU issues
Yeah stuff like that should never pass code review.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8193
  • Country: fi
Re: Prefix or postfix increment in 'for' loops
« Reply #34 on: October 12, 2020, 08:25:58 am »
I would recommend this one relying on UB:

Code: [Select]
#include <stdio.h>

int main()
{
        for(int i=0; i<7; i += i-- - i++)
                printf("asdf\n");
        return 0;
}

Code: [Select]
hrst@Siwa:~$ gcc -Wall t.c
t.c: In function ‘main’:
t.c:5:32: warning: operation on ‘i’ may be undefined [-Wsequence-point]
  for(int i=0; i<7; i += i-- - i++)
                               ~^~
hrst@Siwa:~$ ./a.out
asdf
asdf
asdf
asdf
asdf
asdf
asdf
 

Offline Syntax Error

  • Frequent Contributor
  • **
  • Posts: 584
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #35 on: October 12, 2020, 08:50:15 am »
I would recommend this one relying on UB:

Code: [Select]
{
        for(int i=0; i<7; i += i-- - i++)
                printf("asdf\n");
        return 0;
}
:-+ Tricky
What about i+= --i - --i
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 1228
  • Country: pl
Re: Prefix or postfix increment in 'for' loops
« Reply #36 on: October 12, 2020, 01:35:09 pm »
hamster_nz:
Unless you are really speaking about a wide range of languages, consider specifying which one the question is about. They really are different.

I prefer pre-increment for clarity while merely incrementing, as it does literally what I am wishing to do: it increments. Post-increment usually means “increment, but also retain the previous value and return it”, which — if used the way you have shown — goes into “increment, but also retain the previous value and return it, but actually ignore it.” I see it as unneccessary complexity to think about that additional step.

They are also not identical even in that particular code, at least not in every language. For example in C++ an overloaded postincrement operator may store the value, which is not really needed. The compiler may remove in many cases, but this is not guaranteed.

Doctorandus_P:
In which language? In C this is undefined behaviour, because you are left-shifting a signed variable beyond its range.(1) Note that using uint8_t is irrelevant here: it only tells compilers to perform some additional operations.(2)
____
(1) C99, C11: 6.5.7§4.
(2) Which will be optimized out in any sane compiler nowadays, but this is not guaranteed.
People imagine AI as T1000. What we got so far is glorified T9.
 

Offline PKTKS

  • Super Contributor
  • ***
  • Posts: 1766
  • Country: br
Re: Prefix or postfix increment in 'for' loops
« Reply #37 on: October 12, 2020, 02:01:44 pm »
(..)
Yeah stuff like that should never pass code review.

You will be disappointed on how frequently you will find
what you call "stuff like that"  in low level code.

And  disappointed one more time when you finally
realize that C++ is C with classes

 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3148
  • Country: ca
Re: Prefix or postfix increment in 'for' loops
« Reply #38 on: October 12, 2020, 03:33:46 pm »
In this particular context, the value of the expression is discarded, only the side effect (++) is executed, so there's absolutely no difference.

In practical terms, the compiler will probably keep the loop variable in a register on most CPUs (unless the loop is too long), so the operation is actually an increment of the register.

More importantly, I don't think you should ever worry about such things. The whole point of using C is to outsource the code generation to the compiler. So, you either trust the compiler, or you don't and write your own assembler.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14564
  • Country: fr
Re: Prefix or postfix increment in 'for' loops
« Reply #39 on: October 12, 2020, 03:55:05 pm »
Loops, I most often use for ( i = 0; i < count; i++ ), unless it's a zero indexed array when obviously...
Code: [Select]
for ( i = 0; i < array.count - 1; i++ )

Are you sure?... Maybe if you were using "<=" instead of "<". Or if you were accessing array[i + 1] somewhere inside your loop.

Except darn LUA where arrays index from 1, go figure?

LUA doesn't really have "arrays" to begin with. It has "tables", which are very flexible and can be actually indexed any way you want. You can use tables as "arrays" in LUA, depending on how you build the tables. The default indexing will then be 1,2, ..., but that's just a particular case of using tables. There are several ways in LUA to iterate through a table, most of them not requiring actually knowing what the specific indices are, as opposed to C. And when you do need to know, you can actually specify the indices yourself (which are "keys") instead of letting LUA choose them for you.

That little digression apart, the most usual way IMO to deal with "arrays" starting at index 0 or 1 is just:

Code: [Select]
for (i = 0; i < count; i++) and
Code: [Select]
for (i = 1; i <= count; i++) respectively. That's pretty basic maths.
 

Offline Syntax Error

  • Frequent Contributor
  • **
  • Posts: 584
  • Country: gb
Re: Prefix or postfix increment in 'for' loops
« Reply #40 on: October 12, 2020, 04:51:25 pm »
Are you sure?... Maybe if you were using "<=" instead of "<". Or if you were accessing array[i + 1] somewhere inside your loop.
Well spotted. <= not < .This is why we need code reviews (it stops planes from crashing) :D

Iterating LUA tables, 'in pairs' gives both the value/key and an index. :scared:
« Last Edit: October 12, 2020, 08:49:03 pm by Syntax Error »
 

Offline indeterminatus

  • Contributor
  • Posts: 30
  • Country: at
Re: Prefix or postfix increment in 'for' loops
« Reply #41 on: October 12, 2020, 09:15:51 pm »
Indeed, common mistakes ::). Actually, it's one of the two most difficult problems in computer science:
  • Naming things
  • Cache invalidation
  • Avoiding off-by-one errors
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6327
  • Country: fi
    • My home page and email address
Re: Prefix or postfix increment in 'for' loops
« Reply #42 on: October 12, 2020, 10:11:36 pm »
/* ^ Fix later, too busy right now.  Comments are for those who can't code. */
 

Offline AntiProtonBoy

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: au
  • I think I passed the Voight-Kampff test.
Re: Prefix or postfix increment in 'for' loops
« Reply #43 on: October 13, 2020, 02:56:56 am »
You will be disappointed on how frequently you will find
what you call "stuff like that"  in low level code.
So? It doesn't mean it's okay.

Quote
And  disappointed one more time when you finally
realize that C++ is C with classes
Modern C++ is conceptually very different from "C with classes", looking at a language perspective: RAII, templates, lambdas,  ranges, iterators, exceptions, polymorphism, inheritance, scope resolution, namespaces, constant expressions, concepts, coroutines, move semantics, ..., the list goes on. Not only that, but differences can be discerned even at the low level, when considering memory layout of C++ objects, and aliasing rules. So no, C++ is not just C with classes.
 

Offline indeterminatus

  • Contributor
  • Posts: 30
  • Country: at
Re: Prefix or postfix increment in 'for' loops
« Reply #44 on: October 13, 2020, 07:43:08 am »
The inverse also holds: you can do classes in C.

It's just so much nicer if these are first-class citizens in the syntax of the language.
 

Offline indeterminatus

  • Contributor
  • Posts: 30
  • Country: at
Re: Prefix or postfix increment in 'for' loops
« Reply #45 on: October 13, 2020, 07:56:18 am »
What about i+= --i - --i

Same thing, the result is undefined in C and C++. The order in which the operands are evaluated for the right-hand side of the expression is undefined, which means that either the left-most "--i" or the right-most "--i" might be evaluated first. Since these things have the side-effect of modifying "i", the compiler might generate code (for initial i=10) that may be ( 9 - 8 ) or ( 8 - 9 ), or maybe even ( 8 - 8 ). I'm not so sure about the last one, though. It gets even worse when you look at whole expression.

To summarize, don't use expressions with side-effects, please. Even if the language standard dictates an explicit order of evaluation (like Java does), it gets tedious to reason about it pretty quickly. While these are fun thought experiments, I'd rather not have constructs like that in a production-grade code-base.

[edit: proper boundary conditions added in bold; also, made the parentheses spaced so they would not be converted to emojis  :palm:]
« Last Edit: October 13, 2020, 07:58:33 am by indeterminatus »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf