Я написал этот код C, который, как я предполагаю, предоставляет переносимые теговые указатели:
typedef struct {
char tag[2];
int data;
} tagged_int;
#define TAG(x,y) (&(x)->tag[(y)])
#define UNTAG(x) (&(x)[-*(x)])
int main(void) {
tagged_int myint = {{0,1}, 33};
tagged_int *myptr = &myint;
char *myint_tag_1 = TAG(myptr,1);
char *myint_tag_0 = TAG(myptr,0);
char tag_1 = *myint_tag_1;
char tag_0 = *myint_tag_0;
tagged_int *myint_1 = UNTAG(myint_tag_1);
tagged_int *myint_0 = UNTAG(myint_tag_0);
}
Однако мне любопытно, действительно ли он портативен.
Несмотря на то, что части манипулирования массивом переносимы, можно ли преобразовать char *
в struct *
, если допустить, что char *
относится к первому полю / элементу в struct *
? (Это печально выводит предупреждения компилятора, но я думаю, вы все равно получите те, у которых есть «нормальные» теговые указатели ...)