2

I am trying to get the number of value bits in size_t to be used in the preprocessor directives. Perhaps there is a macro for this? In essence, I would like to achieve something akin to this code where SIZE_T_BITS is a hypothetical macro for the sake of demonstration.

#if SIZE_T_BITS == 32
    // code for 32 bit size_t
#elif SIZE_T_BITS == 64
    // code for 64 bit size_t
#else
    // code for other bit sizes of size_t
#endif
  • 3
    @Jean-FrançoisFabre `sizeof` cannot be understood by preprocessor. –  Dec 24 '17 at 22:08
  • I think the only way is to define such macro for each architecture separately. –  Dec 24 '17 at 22:09
  • related: https://stackoverflow.com/questions/4079243/how-can-i-use-sizeof-in-a-preprocessor-macro. Some clever stuff may answer. – Jean-François Fabre Dec 24 '17 at 22:10
  • `size_t` is defined conditionally, so you have to follow the same conditions for your macro – Jean-François Fabre Dec 24 '17 at 22:11
  • Possible duplicate of [How can I use "sizeof" in a preprocessor macro?](https://stackoverflow.com/questions/4079243/how-can-i-use-sizeof-in-a-preprocessor-macro) – Jean-François Fabre Dec 24 '17 at 22:12
  • @Jean-François Fabre This is not a duplicate, I want to conditionally handle for different bit sizes of `size_t` but that question is about causing a compile error. –  Dec 24 '17 at 22:15

2 Answers2

6

size_t is some unsigned type. Compare the max value to common candidates. The max value is certainly some 2SIZE_T_BITS - 1. The smallest SIZE_MAX may be is 0xFFFF.

#include <stdint.h>
#if (SIZE_MAX == 0xFFFF)
  #define SIZE_T_BITS 16
#elif (SIZE_MAX == 0xFFFFFFFF)
  #define SIZE_T_BITS 32
#elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
  #define SIZE_T_BITS 64
#else
  #error TBD code SIZE_T_BITS
#endif

Although size_t may have paddings bits (this is rare), the about method reflects the number of value bits in size_t. This could differ from the total bits.


Note: SIZE_MAX is defined such that

Each instance of these macros shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. C11 §7.20.3 2

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • My only concern is that what if `SIZE_MAX` is defined like `((unsigned int) 0xFFFFFFFF)` with a cast, then it would not compile –  Dec 24 '17 at 22:26
  • 2
    @everyone the preprocessor understands integers, this will be fine. – Quentin Dec 24 '17 at 22:29
  • @Quentin Thank you that clears up my misunderstanding –  Dec 24 '17 at 22:30
  • 1
    @everyone Answer amended to address your [concern](https://stackoverflow.com/questions/47964313/get-number-of-bits-in-size-t-at-compile-time/47964398#comment82898461_47964398) – chux - Reinstate Monica Dec 24 '17 at 22:30
  • Wait, is it actually guaranteed that `SIZE_MAX` is one less than a power of two? I thought it was, but I also thought it couldn't have padding. – Daniel H Dec 24 '17 at 23:25
  • @DanielH All _unsigned_ types only have value bit and padding bits. There is no reserved value bit pattern - ergo - SIZE_MAX is a p2m1. `SIZE_MAX` is the max of the _type_. Not the max size an object may have - that may be less. `unsigned char` never has padding. Padding is so rarely used these days. – chux - Reinstate Monica Dec 24 '17 at 23:28
-1

This will work for GCC, CLang and MSVC:

#if defined(__x86_64__) || defined(_IA64) || defined(__IA64__) || defined(_M_X64)
  #define SIZE_T_BITS 64
#else 
  #define SIZE_T_BITS 32
c-smile
  • 26,734
  • 7
  • 59
  • 86