Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine pointer size preprocessor C

Tags:

c

pointers

I am working on a software implementation of OpenGL, and OpenGL seems to require that I return 32-bit pointers. To save time, I am putting this into a C equivalent of map with 64-bit systems in order to retrieve 64-bit pointers from 32-bit psuedo-addresses. However, on 32-bit systems, this would cause a hassle, and so I should just use the pointer verbatim.

Here is basically what I want to do in my shared header:

#if <64-bit>
    #include <search.h>
    extern void * pointerTable;
    typedef struct {
          int key;
          void* value;
    } intPtrMap;

    inline int compar(const void *l, const void *r) {
        const intPtrMap *lm = l;
        const intPtrMap *lr = r;
        return lm->key - lr->key;
    }

    inline uint32_t allocate(size) {
        void* result = malloc(size);
        intPtrMap *a = malloc(sizeof(intStrMap));
        a->key = (uint32_t) result;
        a->value = result;
        tsearch(a, &pointerTable, compar);
        return (uint32_t) result;
    }

    inline int getPtr(ptr) {
        intPtrMap *find_a = malloc(sizeof(intPtrMap));
        find_a->key = ptr;
        void *r = tfind(find_a, &root, compar);
        return (*(intPtrMap**)r)->value;
    }
#else
    inline uint32_t allocate(size) {
        return (uint32_t) malloc(size);
    }

    inline uint32_t getPtr(ptr) {
        return (uint32_t) ptr;
    }
#endif

Any suggestions on how to do the first if?

like image 273
Lightning Creations Avatar asked Jul 31 '18 14:07

Lightning Creations


People also ask

What determines the size of a pointer in C?

As we already know, the size of the pointer in C is dependent only on the word size of a particular system. So, the size of a pointer to a pointer should have the usual values, that is, 2 bytes for a 16-bit machine, 4 bytes for a 32-bit machine, and 8 bytes for a 64-bit machine.

How big is a pointer in 64-bit?

In 64-bit data models, pointer sizes are always 64 bits.

What's the size of a pointer in 32-bit environment?

int , long , ptr , and off_t are all 32 bits (4 bytes) in size. int is 32 bits in size. long , ptr , and off_t are all 64 bits (8 bytes) in size.


1 Answers

How to determine pointer size preprocessor C (?)

To determine pointer size in a portable fashion is tricky.

Various pointers sizes

It is not uncommon to have a pointer to a function wider than a pointer to an object or void*.
Pointers to int char, struct can be of different sizes, although that is rare.
So let us reduce the task to determine void * pointer size.

Pre-processor math

PP math is limited, so code needs to be careful. Let us stay with integer math.

(u)intptr_t

The optional types (u)intptr_t, which are very commonly available, are useful here. They allow conversion of a void * to an integer and then to an equivalent void*.

Although the integer type size may differ from the pointer type, that, I assert is rare and detectable with _Static_assert from C11.


Following will handle many C11 platforms. Useful ideas toward a general solution.

#include <stdint.h>

// C11
_Static_assert(sizeof (void*) == sizeof (uintptr_t), 
    "TBD code needed to determine pointer size");

// C99 or later
#if UINTPTR_MAX == 0xFFFF
  #define PTR16
#elif UINTPTR_MAX == 0xFFFFFFFF
  #define PTR32
#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu
  #define PTR64
#else
  #error TBD pointer size
#endif

[Edit 2021]

With Is there any way to compute the width of an integer type at compile-time?, code could use, at compile time, the below to find the width of uintptr_t.

/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
#define UINTPTR_MAX_BITWIDTH IMAX_BITS(UINTPTR_MAX)
like image 74
chux - Reinstate Monica Avatar answered Nov 16 '22 01:11

chux - Reinstate Monica