Casting behavior in C

眉间皱痕 提交于 2019-12-11 05:22:47

问题


I'm currently trying to avoid the pointer arithmetic workings in C to write an emulator.

Usually, if you add 1 to a pointer in C, you add the size of the pointed to object instead. However, I am trying to work with bits and bytes, so this is undesired.

I was wondering if I was using too many parentheses in this example:

*(int16_t *)(((intptr_t)bc)+sp)

And if not, then is it equivalent to this? :

*(int16_t *)((intptr_t)bc+sp)

sp is a page-aligned stack address for my emulator (obtained via. mmap without MAP_FIXED set). It is an intptr_t type.

bc is the name of an int16_t * type. It's a pointer to a combination of two int8_t's.


回答1:


What you're asking about is operator precedence. A full list can be found here.

The '+' operation occurs after a type cast operation. Therefore, you do not need the second layer of parenthesis because the intptr_t cast is applied FIRST to bc, then the result is added to sp.




回答2:


(((intptr_t)bc)+sp) is equivalent t to ((intptr_t)bc+sp).


But this whole "avoid the pointer arithmetic" approach is not portable.

At least 3 concerns:

  • Pointers, converted to an integer, do not certainly maintain the math properties needed.

    // 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
    

The difference as integers may be 16 and not the hoped for 2 -- even if a difference of 2 is more common.

  • Further, with *(int16_t *)((intptr_t)bc+sp), if sp is odd, (int16_t *) can fail due to alignment restrictions.

  • Anti-aliasing issues occur too. @Andrew Henle

Such avoidance of pointer arithmetic though integers has various pitfalls - good luck.



来源:https://stackoverflow.com/questions/55419302/casting-behavior-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!