繁体   English   中英

将指针数组强制转换为“void **”的算术

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM