(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
for (i = 0; i < count; i += 1)
for (i = 0; i < count; i += 1)
for (i=0; i<count; i=i+1)
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.
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.
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).
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.
Loops, I most often use for ( i = 0; i < count; i++ ), unless it's a zero indexed array when obviously...
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)...
i = 0
repeat { i++; // stuff...; } until ( i < count )
i = 0
repeat { // stuff...; } until ( ++i < count )
A moot point when...
FOR i = 0 TO count STEP 1
NEXT i
Just one thought to really upset the interpreter nerds though...
FOR i = 0 TO count STEP 0.000000000000000000000000001
NEXT i
Now hop backwards, just for fun...
for ( uint32_t i = count; i != -1 ; --i )
* Noobs, can you spot the syntax error here?Or just geek out with...
i = -1; while ( ( ++i < count ) ? true : false ; ) { // stuff... }
Yeh, it's like this yawl
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.
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.
I would recommend this one relying on UB:
#include <stdio.h>
int main()
{
for(int i=0; i<7; i += i-- - i++)
printf("asdf\n");
return 0;
}
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
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.
(..)
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
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.
Loops, I most often use for ( i = 0; i < count; i++ ), unless it's a zero indexed array when obviously...
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:
for (i = 0; i < count; i++)
and
for (i = 1; i <= count; i++)
respectively. That's pretty basic maths.
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)
Iterating LUA tables, 'in pairs' gives both the value/key and an index.
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
/* ^ Fix later, too busy right now. Comments are for those who can't code. */
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.
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.
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.
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
]