Search code examples
cemulationpointer-arithmetic

How can I determine if I'm overparenthesizing?


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.


Solution

  • (((intptr_t)bc)+sp) is equivalent 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.