我目前正在尝试避免使用C语言的指针算术来编写模拟器。
通常,如果将1
添加到C中的指针,则会添加指向的对象的大小。但是,我正在尝试使用位和字节,因此这是不希望的。
我想知道在此示例中是否使用了太多的括号:
*(int16_t *)(((intptr_t)bc)+sp)
如果不是,那么这等效吗? :
*(int16_t *)((intptr_t)bc+sp)
sp
是我的仿真器的页面对齐堆栈地址(通过未设置mmap
的MAP_FIXED
获得)。它是intptr_t
类型。
bc
是int16_t *
类型的名称。它是两个int8_t
的组合的指针。
(((intptr_t)bc)+sp)
等效于((intptr_t)bc+sp)
。
但是,整个“避免指针算术”方法是不可移植的。
至少3个问题:
指针,转换为整数,不一定会保持所需的数学属性。
// possible outcome
uint16_t x[2];
printf("%llx\n", (unsigned long long) (intptr_t) &x[0]); // --> abcd0000
printf("%llx\n", (unsigned long long) (intptr_t) &x[1]); // --> abcd0010
作为整数的差可能是16而不是2的期望值-即使更常见的是2的差。
此外,对于*(int16_t *)((intptr_t)bc+sp)
,如果sp
为奇数,则(int16_t *)
可能由于对齐限制而失败。
也会出现抗锯齿问题。 @Andrew Henle
尽管整数有各种陷阱,但还是避免了指针算术,祝您好运。
您要询问的是运算符优先级。可以找到完整列表here.
'+'操作在类型转换操作之后发生。因此,您不需要括号的第二层,因为首先将intptr_t
强制转换应用于bc
,然后将结果添加到sp
。