Home > database >  gcc can't take constexpr address of attribute through member pointer?
gcc can't take constexpr address of attribute through member pointer?

Time:02-22

I'm trying to take the address of an object's attribute through a member pointer at compile-time. The following code compiles fine on MSVC but not on GCC:

#include <optional>

struct S {
    int i = 42;
};

int main() {
    constexpr S obj;
    constexpr auto member = &S::i;
    constexpr auto ptr = std::optional(member);

    // OK
    constexpr auto value = obj.*(*ptr);
    static_assert(value == 42);

    // Doesn't compile on gcc, can't take address through member pointer
    constexpr auto & attr = obj.*(*ptr);
    static_assert(attr == obj.i);
}

GCC gives the following error:

<source>:17:39: error: '(const int&)(& obj)' is not a constant expression
17 |     constexpr auto & attr = obj.*(*ptr);

Here's the code on compiler explorer: https://godbolt.org/z/4WhW3qd7c

I haven't been able to find information about which compiler is wrong here. Can anyone shed some light on this?

CodePudding user response:

The result of a glvalue constant expression can only refer to an object with static storage duration.

obj doesn't have static storage duration, because it is declared at block scope.

You can give obj static storage duration by adding the static keyword at block scope:

static constexpr S obj;

or by declaring it at namespace scope.

  • Related