[ C preprocessor define for value of a given type where every byte is 0xFF? ]
Let's say there's a data type defined as such:
typedef int my_integer_type;
Somewhere else, there exists code like this
#define MAX_MY_INTEGER_TYPE 0xFFFFFFFF
However, if my_integer_type later is changed to 8 bytes instead of 4, MAX_MY_INTEGER_TYPE will need to be updated as well. Is there a way for MAX_MY_INTEGER_TYPE to be a bit smarter, to basically represent the number of bytes in my_integer_type all set to 0xFF?
I realize there are other traditional ways to get the maximum integer size (like here: maximum value of int), but my actual use case is a bit more complex and I cannot apply those solutions.
Answer 1
You can calculate the maximum size of an integer like using bit-wise operations.
For an unsigned integer you can do it like this:
const unsigned int MAX_SIZE = ~0;
or, you can do it like this if your compiler does not complain:
const unsigned int MAX_SIZE = -1;
EDIT
For your particular case, it seems you want to be able to calculate the maximum value of a signed type. Assuming the sign is calculated using 2's complement (as is in most systems), you can use this methods:
const my_integer_type MAX_MY_INTEGER_TYPE =
~((my_integer_type)1 << (sizeof(my_integer_type) * CHAR_BIT) - 1);
So, what I do here is calculate the size of the type. Whatever the size is, I'm going to subtract 1 from that. I use the resulting number to shift a 1 to the left most position. Then I invert the whole thing.
Let's say that my_integer_type is 1 bytes. That is 8 bits, meaning that the shift amount is 7. I take the 1 and shift it. The result of the shift looks like this: 0x80
. When you invert it, you get this: 0x7f
. And that is the maximum value (of course, assuming it uses 2's complement).
Note that I did not used the preprocessor. Unfortunately, the preprossor is a simple find and replace tool that is not aware of types in C. So, you'll have to use constants.
Answer 2
No, for signed integer types there is basically no way to calculate the maximum values for the type. This is the main reason why all the predefined MAX
-macros such as INT_MAX
exist. To avoid the maintenance problem you could go the other way round
#include <limits.h>
#define MY_INTEGER_TYPE_MAX 0xFFFF...FFF // whatever number of 'F' you chose
#if MY_INTEGER_TYPE_MAX <= SCHAR_MAX
typedef signed char my_integer_type;
#elsif MY_INTEGER_TYPE_MAX <= SHRT_MAX
typedef signed short int my_integer_type;
#elsif MY_INTEGER_TYPE_MAX <= INT_MAX
typedef signed int my_integer_type;
#elsif MY_INTEGER_TYPE_MAX <= LONG_MAX
typedef signed long int my_integer_type;
#elsif MY_INTEGER_TYPE_MAX <= LLONG_MAX
typedef signed long long int my_integer_type;
#else
typedef intmax_t my_integer_type;
#endif
You see that it is not a very long list of cases that you have to differentiate.
Answer 3
Not clear is OP wants "every byte is 0xFF" or the maximum integer value.
1) [Edit] Assuming "every byte is 0xFF" is OP's goal, @Eric Postpischil idea is sound and simple
// Better name: MY_INTEGER_TYPE_ALL_BITS_SET
#define MAX_MY_INTEGER_TYPE (~ (my_integer_type) 0)
2) Interesting OP is asking for "value of a given type where every byte is 0xFF?" and then proceeds to call it "MAX_MY_INTEGER_TYPE". This does sound like an unsigned
as the maximum signed
value is rarely (if ever) "every byte is 0xFF". Using -1
as suggested by @H2CO3 looks good.
#define MAX_MY_INTEGER ((my_integer_type) 0 - 1).
3) Not yet answered: if OP wants max value and my_integer_type
could be signed (and not assuming 2's complement).