Increment, decrement, overflow, and underflow

I

Ian Pilcher

I'm trying to figure out if an increment to a variable of an integer
type, followed by a decrement, (or vice versa) is guaranteed to restore
the variable to its initial value, even if the first operation causes
the variable to overflow/underflow.

In other words, if foo_t is an integer type, are the following two
functions guaranteed to *always* return a non-zero value?

int check_overflow(foo_t f)
{
foo_t g = f;
g++;
g--;
return (f == g);
}

int check_underflow(foo_t f)
{
foo_t g = f;
g--;
g++;
return (f == g);
}

Thanks!
 
B

Ben Pfaff

Ian Pilcher said:
I'm trying to figure out if an increment to a variable of an integer
type, followed by a decrement, (or vice versa) is guaranteed to restore
the variable to its initial value, even if the first operation causes
the variable to overflow/underflow.

This is only true for unsigned integer types, which are
guaranteed to "wrap around". Signed integer types might signal
an error on overflow or underflow.
 
P

Peter Nilsson

Ian said:
I'm trying to figure out if an increment to a variable of an
integer type, followed by a decrement, (or vice versa) is
guaranteed to restore the variable to its initial value, even
if the first operation causes the variable to overflow/underflow.

For signed integers, no. You can't undo the effects of undefined
behaviour once it's happened. You have to pre-emptively detect
that an overflow will occur and deal with it before the
operation in question.
In other words, if foo_t is an integer type, are the following two
functions guaranteed to *always* return a non-zero value?

int check_overflow(foo_t f)
{
foo_t g = f;
g++;
g--;
return (f == g);
}

If f < FOO_MAX, or if foo_t is unsigned and of rank equal or
higher than int, or if foo_t promotes to unsigned int, or if
foo_t promotes to int and FOO_MAX < INT_MAX, then yes.
Otherwise, no.
 
I

Ian Pilcher

Ben said:
This is only true for unsigned integer types, which are
guaranteed to "wrap around". Signed integer types might signal
an error on overflow or underflow.


Thanks for the response. I momentarily forgot about trap
representations.

Fortunately, I'm currently worried about decrementing a size_t which may
be 0, so I guess I'm OK.

Thanks!
 
P

Peter Nilsson

Ian said:
Thanks for the response. I momentarily forgot about trap
representations.

Trap representations are irrelevant for arithmetic operations.
Fortunately, I'm currently worried about decrementing a size_t
which may be 0, so I guess I'm OK.

Yes. If it is 0, then a decrement will produce SIZE_MAX.

[Note however that incrementing a size_t object with value
SIZE_MAX is _theoretically_ problematic since size_t may
have rank lower than int, and SIZE_MAX == INT_MAX is a
possibility. This is highly unlikely in practical
implementations though. I.e. it's one those "well worth
ignoring" elements of standard C.]
 
C

CBFalconer

Ian said:
I'm trying to figure out if an increment to a variable of an integer
type, followed by a decrement, (or vice versa) is guaranteed to restore
the variable to its initial value, even if the first operation causes
the variable to overflow/underflow.

No, not for signed types. For unsigned, yes. The result of signed
overflow is undefined behavior, which means anything at all may
occur, including what you want.
 

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

Similar Threads


Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top