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