Search code examples
c++clangclang-tidy

Integer to pointer cast pessimism optimization opportunities


The from_base function returns the memory address from the base to a selected value in a program. I want to retrieve this value and return it in a function, however, I am getting a warning that says integer to pointer cast pessimism optimization opportunities.

DWORD chat::client() {
    return *reinterpret_cast<DWORD*>(core::from_base(offsets::chat::client));
}

I am also getting this warning when casting a function from the program:

auto og_print = reinterpret_cast<chat::fn_print_chat>(core::from_base(offsets::chat::print));

I don't understand why I am getting a warning from clang-tidy about integer to pointer cast pessimism optimization opportunities

performance-no-int-to-ptr

I looked it up, but I can't figure it out. The code works, and gets the correct value. I am just concerned about the warning.


Solution

  • If a program performs a computation like:

    char x[10],y[10];
    int test(ptrdiff_t i)
    {
      int *p = x+i;
      *p = 1;
      y[1] = 2;
      return *p;
    }
    

    a compiler would be reasonably entitled to assume that because p was formed via pointer arithmetic using x, it could not possible equal y+1, and thus the function would always return 1. If, however, the code had been written as:

    char x[10],y[10];
    int test(ptrdiff_t i)
    {
      int *p = (char*)((uintptr_t)x + i);
      *p = 1;
      y[1] = 2;
      return *p;
    }
    

    then such an assumption would be far less reasonable, since unsigned numerical semantics would define the behavior of uintptr_t z = (uintptr_t)(y+1)-(uintptr_t)x as yielding a value such that x+z would equal (uintptr_t)(y+1).

    I find the apparent caution clang exhibits here a bit surprising, given that clang is prone to assume that, given some pointer char*p, it's not possible for p to equal y if (uintptr_t)p to equal (uintptr_t)(x+10) and yet for p to equal y. The Standard doesn't forbid such an assumption, but then again it also wouldn't forbid an assumption that code will never use the result of any integer-to-pointer conversion for any purpose other than comparisons with other pointers. Implementations that support type uintptr_t should of course offer stronger guarantees about round-tripped pointers which than merely saying they may be compared for equality with the originals, but the Standard doesn't require such treatment.