change index between 0 and 1

J

Joe Wright

pete said:
That return statement has undefined behavior.

unsigned inc(void)
{
static unsigned i;

return i++ & 1;
}
Bless you my son. The assignment was questionable perhaps. But why
unsigned instead of int? The variable i is initialized to 0 by the
compiler and has no chance of exceeding 2. Signedness is not an issue
here. What's the problem?
 
C

Chris McDonald

Joe Wright said:
Bless you my son. The assignment was questionable perhaps. But why
unsigned instead of int? The variable i is initialized to 0 by the
compiler and has no chance of exceeding 2. Signedness is not an issue
here. What's the problem?


But why, oh why, are people proposing these fancy
power-of-2-based-modulo-or-masking-solutions over the oft offered:

i = 1 - i;
?
 
A

Antonio Contreras

int will cause undefined behaviour when it overflows, unsigned won't.
But why, oh why, are people proposing these fancy
power-of-2-based-modulo-or-masking-solutions over the oft offered:

i = 1 - i;
?

Because beauty is in the eye of the beholder and there may be people
who happen to like other solutions better.

The modulus solution below has the clear advantage of being scalable to
larger array sizes.

#define ARRAY_SIZE 2

int index (void) {
static int i = 0;
return i = (i + 1) % ARRAY_SIZE;
}

If I were absolutely sure that I'll never need a larger array I'd go
with another offered solution:

int index (void) {
static int i = 1;
return i = !i;
}

which in turn has the advantage that if i somehow (wild pointers,
buffer overflow...) gets a value different than 0 or 1, it will return
to sequence in the next call (the damage may have been done by now, but
that's another matter).
 
O

Old Wolf

Joe said:
Bless you my son. The assignment was questionable perhaps.
What's the problem?

Your suggestion is undefined because it modifies the value of
`i' twice between sequence points.
 
C

Chris McDonald

Antonio Contreras said:
If I were absolutely sure that I'll never need a larger array I'd go
with another offered solution:
int index (void) {
static int i = 1;
return i = !i;
}
which in turn has the advantage that if i somehow (wild pointers,
buffer overflow...) gets a value different than 0 or 1, it will return
to sequence in the next call (the damage may have been done by now, but
that's another matter).

Even better, and meets the OP's requirements; thanks!
 
K

Keith Thompson

Joe Wright said:
pete said:
Joe Wright wrote: [...]
Too complicated. Assume a function to return alternatively 0, 1 then 0
etc. It might look like ..

int inc(void) {
static int i;
return i = i++ & 1;
}


That return statement has undefined behavior.

unsigned inc(void)
{
static unsigned i;

return i++ & 1;
}
Bless you my son. The assignment was questionable perhaps. But why
unsigned instead of int? The variable i is initialized to 0 by the
compiler and has no chance of exceeding 2. Signedness is not an issue
here. What's the problem?

In pete's solution, i is incremented every time the function is
called. The value returned by the function will always be either 0 or
1, but the value of i will increase without bound. There could be two
reasons to make it unsigned: bitwise operations on signed types are
generally to be avoided, and unsigned int has defined behavior on
overflow.

But allowing i to increase without bound is a kludge. It's much
simpler to keep i itself in the range 0..1. Something like
i = 1 - i;
return i;
is longer but *much* simpler.
 
P

pete

Joe said:
Bless you my son. The assignment was questionable perhaps. But why
unsigned instead of int?

I'm letting the i variable roll over at UINT_MAX.
The variable i is initialized to 0 by the
compiler and has no chance of exceeding 2. Signedness is not an issue
here. What's the problem?

Like "Old Wolf" said:
"modifies the value of `i' twice between sequence points"

i = i++; /* No good */

Assignment is not a sequence point.
 
I

Ian Collins

Chris said:
But why, oh why, are people proposing these fancy
power-of-2-based-modulo-or-masking-solutions over the oft offered:

i = 1 - i;
?
Or even i^=1, which should be very efficient.
 
K

Keith Thompson

Ian Collins said:
Or even i^=1, which should be very efficient.

Any improvement in efficiency is unlikely to be worth the loss of
clarity. Remember the Rules of Optimization.
 
I

Ian Collins

Keith said:
Any improvement in efficiency is unlikely to be worth the loss of
clarity. Remember the Rules of Optimization.
Clarity is in the eye of the beholder!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top