ideasman42
ideasman42

Reputation: 48038

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.

Upvotes: 9

Views: 9777

Answers (2)

user3079266
user3079266

Reputation:

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!

Upvotes: 4

dlask
dlask

Reputation: 8982

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");

Upvotes: 1

Related Questions