c++stackheap-memorymemory-addressdesign-decisions

If the stack grows at numerically lower address why does pointer comparison reverses this?


Since the stack grows downwards, ie towards numerically smaller memory addresses why does &i < &j is true. Correct me if I'm wrong, but I'd imagine this was a design decision of C creators (that C++ maintains). But I wonder why though.

It is also strange that a heap-allocated object pin lies at numerically higher memory address than a stack variable and this also contradicts the fact that the heap lies at numerically smaller memory addresses than the stack (and increases upwards).

#include <iostream>

int main()
{
    int i = 5;                  // stack allocated
    int j = 2;                  // stack allocated
    int *pi = &i;               // stack allocated
    int *pj = &j;               // stack allocated

    std::cout << std::boolalpha << '\n';
    std::cout << (&i < &j) && (pi < pj) << '\n';            // true
    struct S
    {
        int in;
    };
    S *pin                      // stack allocated
        = new S{10};            // heap allocated
    std::cout << '\n' << (&(pin->in) > &i) << '\n';         // true
    std::cout << ((void*)pin > (void*)pi) << '\n';          // true
}

Am I right so far and if so why C designers reversed this situation that numerically smaller memory addresses appear higher (at least when you compare the pointers or through the addressof operator &). Was this done just 'to make things work'?


Solution

  • Correct me if I'm wrong, but I'd imagine this was a design decision of C creators

    It is not part of the design of the C language, nor C++. In fact, there is no such thing as "heap" or "stack" memory recognised by these standards.

    It is an implementation detail. Each implementation of each language may do this differently.


    Ordered comparisons between pointers to unrelated objects such as &i < &j or (void*)pin > (void*)pi have an unspecified result. Neither is guaranteed to be less or greater than the other.

    For what it's worth, your example program outputs three counts of "false" on my system.