Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a portable way to do tagged pointers in C?

I have written this C code which I assume provides portable tagged pointers:

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

However, I am curious about whether it really is portable.

While the array manipulation parts are portable, is char * to struct * conversion portable, assuming the char * refers to the first field/element in the struct *? (This outputs compiler warnings sadly, but I guess you'd get those with "normal" tagged pointers anyway...)

like image 850
SoniEx2 Avatar asked Oct 29 '22 09:10

SoniEx2


1 Answers

#define UNTAG(x) (&(x)[-*(x)]) does not serve as a pointer to tagged_int; it is a char * and will not be automatically converted.

If you insert a cast, #define UNTAG(x) ((tagged int *)(&(x)[-*(x)])), then this is almost legal per C 2011 (draft N1570) 6.7.2.1 15, “A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa.” An impediment here is that you have a pointer to the first member of the first member (that is, to a char that is element 0 of the array that is the first member). Depending on how strictly you interpret certain things in the C standard, this might or might not be considered supported (and might be mitigated by using two casts, as in #define UNTAG(x) ((tagged int *)(char (*)[2])(&(x)[-*(x)]))). In any case, I would expect it to be portable, as a C implementation would have to go out of its way to break this while supporting other accepted C semantics.

like image 110
Eric Postpischil Avatar answered Nov 15 '22 12:11

Eric Postpischil