首页 > 解决方案 > 如何确定我是否过度使用括号?

问题描述

我目前正在尝试避免 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's 组合的指针。

标签: cemulationpointer-arithmetic

解决方案


(((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 *)则由于对齐限制,可能会失败。

  • 也会出现抗锯齿问题。@安德鲁·亨利

尽管整数这样避免指针算术有各种陷阱 - 祝你好运。


推荐阅读