TAGS :Viewed: 2 - Published at: a few seconds ago

[ 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).