【发布时间】:2018-07-01 17:02:11
【问题描述】:
我已经编写了这个 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 * 中的第一个字段/元素? (这很遗憾地输出编译器警告,但我猜你无论如何都会得到带有“正常”标记指针的那些......)
【问题讨论】:
-
不确定您要在这里做什么。标签打算提供什么?
-
@SteveSummit 这是一个标记指针。它提供了一些数据作为指针的一部分,而不是结构的一部分。
-
对我来说看起来是可移植的,但我没有看到任何用例,(
(&(x)[-*(x)])是不可读的,例如((x) - *(x))看起来更好,我们看到这段代码现在看起来很奇怪) -
我不清楚你的实现,但我没有看到指针中存储了任何标签。 Tagged pointer 表示指针本身的某些位用于标记。您只有结构中的数据和标记,然后指向结构。即使您将指针存储在
data字段中,显然它也不是可移植的,因为指针不是int。它们只能转换为(u)intptr_t -
@SoniEx2 好的,但我真的没有看到您将任何额外数据存储为指针的一部分。 (这是一种流行的技术,但我相信它总是不可移植,因为它完全依赖于机器和系统,指针中是否有任何位保证不会被使用,这样你就可以“窃取”它们供您自己使用而不会产生不良影响。)
标签: c pointers language-lawyer portability