[英]Arithmetic with array of pointers casted to `void **`
我知道 C 标准承诺指向任何对象的指针都可以往返于void *
并返回。 换句话说,
T obj;
assert(&obj == (T *) (void *) &obj);
现在,我想知道指针算法。 它是如何遵循的/它在哪里说的
T *arr[2] = {0};
assert(arr[1] == (T *) (((void **)arr)[1]))
作品? 这还能保证吗?
我有一种预感,答案是“不能保证”甚至“这是 UB”。 原因是,据我“所知”, void *
的表示不需要等于其他指针的表示。 例如,如果 void 指针的大小比其他指针大,则void **
上的指针算法可能无法工作。 所以除非以上是合法的,我想知道如果我想用通用代码对指针数组进行操作,我应该怎么做。
我有一种预感,答案是“不能保证”甚至“这是 UB”。 原因是,据我“所知”,
void *
的表示不需要等于其他指针的表示。 例如,如果 void 指针的大小比其他指针大,则void **
上的指针算法可能无法工作。
你是对的,你的推理是对的,至少在实践意义上是对的。 从标准的角度来看,有点不清楚以哪种方式来论证评估表达式((void **)arr)[1]
会产生未定义的行为。 我倾向于这样做:该表达式等效于*(((void **)arr) + 1)
,并且由于(void **)arr
实际上并未指向数组,因此添加指针会产生未定义的行为void *
。 但还有一个事实,即*(((void **)arr) + 1)
是void *
,并且,根据严格的别名规则,如果它实际上不引用,则评估会产生未定义的行为一个void *
。
我想知道如果我想用通用代码对指针数组进行操作,我应该怎么做。
C 没有表示通用指针数组类型的机制。 特别是, void *arr[DIMENSION]
形式的数组和void **
类型的指针不是通用的。 但是,您可以使用这些特定类型的数组和指针,并使用从任意其他(对象)指针类型转换的指针加载它们。
根据您要执行的特定操作,可能还有其他选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.