首页 > 解决方案 > 已知大小的未指定类型的指针算法

问题描述

void * ptr = NULL; // array of unspecified 13-byte type

for (int i = 0; i < 10; i++) {
    printf("%i ", ((char (*) [13]) ptr) + i);
}

putchar('\n');

输出:

0 13 26 39 52 65 78 91 104 117

所以这有效(至少在 GCC 上),但是我如何声明一个类型的变量,(char (*) [13]这样我就不必每次想对该指针执行指针算术时都进行强制转换?

这种行为甚至是可移植的吗?

标签: cvoid-pointerspointer-arithmetic

解决方案


已知大小的未指定类型的指针算法

这种行为甚至是可移植的吗?

严格地说:也许:

需要深入了解C17 6.3.2.3 Pointers

像下面这样的东西依赖于&fred[0]能够ptr毫无困难地转换的价值。许多实现将毫无问题地处理这个问题,但ptr它是指向数组的指针,而不是指向char. 一直ptr是指针char,没问题。

认为因为ptr两者fred都有相同的对齐要求 - 代码是可以的。

typedef something unspecified_13_byte_type;
assert(sizeof(unspecified_13_byte_type) == 13);

#define N
unspecified_13_byte_type fred[N];

char (*ptr)[13] = (void *) fred;
for (int i = 0; i < N; i++) {
  // printf("%i ", ((char (*) [13]) ptr) + i);
  printf("%p ", (void *)  (((char (*) [13]) ptr) + i));
}
puts("");

更深一点: if somethingis some struct, then ptrand&fred[0]不必是相同的编码甚至相同的大小 - 即使它们很好地相互转换并相互等同。 struct指针,并且char *可能与通常预期的不同 - 即使这种差异在今天非常罕见。


推荐阅读