I have some code in a function which will change/update values with the increment/decrement operator. For example:
static void update_value(char op)
{
if (op == '+')
value++; // uint32_t global value
else
value--;
}
The function does not check whether we've gone over/under max/min values. So the caller can call it 20 times when value is say 16. resulting in 2^32 - 1 - 4.
I'd like to guard against that but I would like to use standard library constants. I remember there was a size_t (or similar) variable that would represent the largest number that a uint32_t can hold.
I can't remember the exact constants nor the header where they were defined. Any help?
In C the header file you want is <stdint.h>
and the constant is UINT32_MAX
static void update_value(char op)
{
if (op == '+')
if ( value < (UINT32_MAX - 1))
value++; // uint32_t global value
else
printf("too big!\n");
else
if (value > 0)
value--;
else
printf("too small!\n");
}
For C++ you can use any number of solutions found here: What's the C++ equivalent of UINT32_MAX?
I've found that the most general solution is to check if the incremented value is in fact greater than the previous value, or if the decremented value is smaller than the previous value. This works only if the value is unsigned, independently of the size of the variable, and is pretty much as portable as C code ever gets.
static void update_value(char op)
{
if (op == '+') {
if (value + 1 > value) value ++;
} else {
if (value - 1 < value) value --;
}
}
Note that the code may happen to work with signed values, but per the C standard this would be undefined behavior, and the compilers are free to replace if (value + 1 > value) ...
with if (1) ...
. You should not use this code with signed values unless you have a process in place to audit the generated object code after it has been linked.
With gcc and clang, you'd need to add -fwrapv
option to let this code work for signed values; with other compilers your mileage may vary.
A sane way of doing this is to be type-specific and use constants from limits.h
. For example:
#include "limits.h"
static void update_int(char op, int *value)
{
int val = *value; // ignoring NULL pointer dereference
if (op == '+') {
if (val != INT_MAX) *value = val + 1;
} else {
if (val != INT_MIN) *value = val - 1;
}
}
static void update_int(char op, unsigned int *value)
{
unsigned int val = *value; // ignoring NULL pointer dereference
if (op == '+') {
if (val != UINT_MAX) *value = val + 1;
} else {
if (val != UINT_MIN) *value = val - 1;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With