我在普通C中有一个void*
,我在浏览一些非结构化数据时正在使用它,并且我想在我去的时候使用dereference和autoincrement进行投射。我想写下以下内容:
void* ptr = /*something*/;
uint16_t i = *((uint16_t*) ptr)++;
编译器对象并告诉我“左值作为递增操作数”,但我想我认为指针作为指针仍然可以作为左值。
显然,我的意图是让ptr现在指向超出之前指向的两个字节。我无法删除围绕ptr转换的括号,因为++
的优先级高于强制转换,所以这不会像我想要的那样工作:
int i = *(uint16_t*) ptr++;
我当然可以做自己的增量,如下所示,但我希望有一些优雅和简洁的东西:
int i = *(uint16_t) ptr;
ptr += sizeof(uint16_t);
这样做的好方法是什么?
答案 0 :(得分:1)
写起来最简单:
uint16_t *uptr = ptr;
uint16_t i = *uptr++;
ptr = uptr; // if required
您可以重新构建较大的代码,以尽可能多地使用uint16_t *
,从而无需进行如此多的转换。
答案 1 :(得分:0)
长时间不允许将指针强制转换为其他类型,可能是自C89以来。原因是从一种指针到另一种类型的转换可以改变表示,因此可能不会引用同一个对象。
您必须将表达式拆分为2个语句:
void *ptr = /*something*/;
uint16_t i = *(uint16_t*)ptr;
ptr = (uint16_t*)ptr + 1;
或者,如果单个表达式的上下文命令,您可以使用此hack:
uint16_t i = ((uint16_t*)(ptr = (uint16_t*)ptr + 1))[-1];
或者如果你想混淆更多这个:
uint16_t i = (-1)[(uint16_t*)(ptr = (uint16_t*)ptr + 1)];