Reputation: 48038
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
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
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