Checking the sizeof an integer type in the preprocessor
Asked Answered
I

3

16

How can I check the size of an unsigned in the preprocessor under g++? sizeof is out of the question since it is not defined when during preprocessing.

Induce answered 6/4, 2010 at 13:1 Comment(3)
It is not well answered there.Induce
@Lucero: That only answers why sizeof is out of the question that myahya is aware of.Almund
Maybe #1506082 covers your question?Endmost
T
27

This may not be the most elegant method, but one thing that you may be able to leverage is UINT_MAX defined in "limits.h". That is, ...

if UINT_MAX == 65535, then you would know that sizeof (unsigned) = 2

if UINT_MAX == 4294967295, then you would know that sizeof (unsigned) = 4.

and so on.

As I said, not elegant, but it should provide some level of usability.

Hope this helps.

Tackling answered 6/4, 2010 at 13:7 Comment(6)
This is a valid answer that is not in the "duplicate" question. So, I've voted to reopen.Kamat
The preprocessor should be able to do some math, something like #if UINT_MAX >> 8 == 0 // 1 byte ... #elif UINT_MAX >> 16 == 0 //two bytes etc?Almund
Technically the size of the integer could be bigger than this technique predicts, since unsigned is allowed to have padding bits, or smaller since CHAR_BIT need not be 8. So for correctness it might be worth also asserting somewhere (in a test, perhaps), that sizeof does give the size expected. In practice you can say with high confidence that it isn't gonna happen.Expendable
Thanks, I added an answer just to get around the need for explicitly plugging in values.Induce
If UCHAR_MAX == UINT_MAX then sizeof(1U) probably is one. But it still may be 3.Precessional
You assume CHAR_BIT==8, which is not a requirement.Jamiejamieson
I
11

Based on Sparky's answer, here is a way that would look a bit nicer (by eliminating the explicit numbers)

#include <limits.h>
#include <stdint.h>

//Check if size if 4bytes
#if UINT_MAX == UINT32_MAX

....

#endif

<limits.h> defines INT_MAX and <stdint.h> defines UINT32_MAX. Generally, <stdint.h> gives integer types with specified widths.

Induce answered 6/4, 2010 at 13:15 Comment(2)
This works under gcc, under g++ it can be problematic. Sparky's solution is more generalInduce
The problem is that what if UINT_MAX doesn't fit into a preprocessor integer? The preprocessor arithmetic in #if directives works with a signed type. Modern ISO C defines that as being the type intmax_t: the widest signed type available in the implementation. What if unsigned int has the same width? Then UINT_MAX is out of range. Can we trust that there will be an implementation-defined conversion in the #if directive, like in an ordinary C expression?Zebadiah
B
0

If you want to check the value of the expression sizeof(unsigned) on the equality with a certain number, you can use bitwise shift to the left (<<). This operation just works with type unsigned.

If you want to check condition sizeof(unsigned) <= 32, then it is enough to check the condition 1 << 32 == 0. Accordingly, to test the condition sizeof(unsigned) > 31, you need to test 1 << 31 != 0. As a result, to test the conditions sizeof(unsigned) == 32 you can use this:

#if (1 << 32 == 0) && (1 << 31 != 0)
...
#endif
Berube answered 22/7 at 0:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.