简体   繁体   中英

Pointer to type within a macro, C

I've run into a problem when attempting to express the pointer to a type within a macro.

Take this simple example.

#define INDEX_OF_DATA(data, type, index) \
    ((type *)data)[index]

This works:

INDEX_OF_DATA(buffer, float, 3);

Where this fails:

INDEX_OF_DATA(buffer, float[2], 3);

Because the cast should be (float(*)[2]) .

Is there a way to express "the pointer of a type " , ...without using typeof ? (which isn't standard C).


Note, there are of course other ways to make this specific example work. cast to char and offset by sizeof(type) * index for example. But am interested in a way to express pointer to type in C.

Doing heavily complicated stuff with C types may be a fun sport, but it's extremely confusing in real code.

To avoid wrecking their heads over complicated pointer expressions too much, people often use typedef !

If you typedef all the types that you expect to use with this macro of yours, you won't have any problems. Observe:

#include <stdlib.h>

#define INDEX_OF_DATA(data, type, index) \
    ((type *)data)[index]


int main(void) {
    float (*buffer)[2] = malloc(4 * sizeof(float[2]));

    typedef float t_f2arr[2];

    INDEX_OF_DATA(buffer, t_f2arr, 3)[0] = 1.1f;

    return 0;
}

This does exactly what you intended!

If we want to preserve the original macro, we can use this trick:

#define INDEX_OF_DATA(data, type, index) ((type*)data)[index]

struct mystruct { float f[2]; };
mystruct* p = &INDEX_OF_DATA(buffer, mystruct, 3);

Unfortunately this solution could be affected by struct padding so it's better to check:

static_assert(sizeof(mystruct) == sizeof(float (*)[2]), "padding found");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM