Home > Blockchain >  constexpr iterate over section in memory
constexpr iterate over section in memory

Time:03-11

I am trying to turn a function, createArray, into a constexpr function. This function creates an array from a contiguous section in memory marked by two arbitrarily named variables _start_array and _stop_array. I am able to iterate between the two and when the program is ran it prints

foo
bar
baz

This is the code so far:

#include <iostream>
#include <string>
#include <array>

struct element {
    std::string_view value;
};

__attribute__( (used, section("array$a" )) ) unsigned int _start_array = 0xdeadbeef;
__attribute__( (used, section("array$b" )) ) element _element1_array = { .value = "foo" };
__attribute__( (used, section("array$b" )) ) element _element2_array = { .value = "bar" };
__attribute__( (used, section("array$b" )) ) element _element3_array = { .value = "baz" };
__attribute__( (used, section("array$c" )) ) unsigned int _stop_array = 0xdeadc0de;

std::array< element, 3 > createArray () { // TODO: constexpr
    std::array< element, 3 > array;
    
    int i = 0;
    for ( element* it = reinterpret_cast< element* >( &_start_array   sizeof( int ) ); it < reinterpret_cast<element*>(&_stop_array); it   ) {
        array[ i   ] = *it;
    }
    
    return array;
}

int main ( int argc, char* argv[] ) {
    for ( auto i : createArray() ) {
        std::cout << i.value << std::endl;
    }
}

I am using MinGW on Windows.

CodePudding user response:

During constant expression evaluation, the C object model is treated as reality, not a fiction created by a piece of paper. This means that anything which would be undefined behavior at runtime becomes ill-formed during constant evaluation.

As such, pointers in constant evaluation are not merely numbers. They are pointers to a specific object with full and complete knowledge of what that means. So converting a pointer value to an integer makes no sense.

And even if it did, what are you going to do with it? The address has no relation to the address of any other object. The address cannot be manipulated and then converted to a pointer to some other object, because that's not how things work at compile-time. Again, the object model is taken seriously at compile-time. If you get a pointer from something, the system needs to be able to verify that the "something" points to a real object of that type (or a type appropriate to the pointer type). This requires a compile-time pointer to be more than just an address.

Put simply, you cannot "treat the memory between _start and _stop as an array" at compile-time, because it isn't an array. You cannot just pretend things are a certain way at compile-time. To be fair, you can't do that at runtime either with well-defined behavior; it's just that the compiler won't stop you.

CodePudding user response:

No, there is no standard way to reinterpret pointers in constexpr contexts.

Furthermore, accessing objects through reinterpreted pointers is well defined only in a few specific cases. Arbitrary T* isn't necessarily such case.

Iterate over a section in memory between two variables

There's no standard way to do this in general. There's generally not even a guarantee that such memory is allocated for the process.

If the variables in question are members of a standard layout class, then this may be achievable, but I can't think of a constexpr way.

  • Related