我在遍历一些非结构化数据时使用的是纯C语言中的void*,我想在进行过程中使用取消引用和自动递增进行转换。我想写以下内容:

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);


有什么好方法吗?

最佳答案

很长一段时间以来,不允许将强制转换为其他类型的指针递增,这可能是从C89开始的。原因是从一种类型的指针到另一种类型的指针的转换可以更改表示,因此可能不会引用同一对象。

您必须将表达式拆分为2个语句:

void *ptr = /*something*/;
uint16_t i = *(uint16_t*)ptr;
ptr = (uint16_t*)ptr + 1;


或者,如果对单个表达式使用上下文命令,则可以使用此技巧:

uint16_t i = ((uint16_t*)(ptr = (uint16_t*)ptr + 1))[-1];


如果您想进一步混淆,也可以使用以下方法:

uint16_t i = (-1)[(uint16_t*)(ptr = (uint16_t*)ptr + 1)];

关于c - 如何在C中取消引用并自动递增强制转换指针?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34889130/

10-11 23:14
查看更多