Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using nameof_member on structures with non-constexpr destructor fails to compile on MSVC #49

Closed
kamchatka-volcano opened this issue Dec 5, 2022 · 3 comments

Comments

@kamchatka-volcano
Copy link
Contributor

Hi, I finally got around to updating nameof in my project to test the fix of #46 by @schaumb.
Unfortunately, it doesn't work when TestStruct has a member with a non-constexpr user-provided constructor. Is it possible to fix it?
I looked into the source, but I don't understand the union trick used in the member_name_v implementation for MSVC, so I can't tell if it can be fixed.

As previously, the following code doesn't compile on MSVC (2022) using the latest master of nameof, but works fine with clang and gcc

struct Foo{
    ~Foo(){};
};

struct TestStruct{
    std::string teststringfield = std::string{nameof::nameof_member<&TestStruct::teststringfield>()};
    Foo foo;
};
@schaumb
Copy link
Contributor

schaumb commented Dec 5, 2022

Hi @kamchatka-volcano !
The current solution works only if the TestStruct destructor is constexpr, the default for trivially_destructible classes, and if all member destructor is constexpr.

So If Foo's destructor is constexpr, then it will work.

I Investigate any other solution for not constexpr destructor, but I think this is an MSVC compiler or C++std bug. It must not to call members user-defined destructor in the union, but the constexpr-ness property is inherited somewhy, based on the compiler error

TODO doc!

note:
the union trick is: We create a constexpr static variable, which is a union with a trivial active type (char) and the class (T) of the owner of the member. We cannot use the not active member (T), but we can query the member pointer of the constexpr union variable. This "constexpr relative" memory information is passed through a __FUNCSIGN__, and it will contain the name. So we won't create the TestStruct, and shouldn't be called the destructor either.
sidenote: this hack is needed because __FUNCSIGN__ is not contain the member pointer name default, only the offset

@kamchatka-volcano
Copy link
Contributor Author

I see, that's what I was afraid of) In my project TestStruct is user-provided and the requirement of constexpr dtr is a pretty heavy restriction.
Anyway, thanks a lot for the detailed explanation, now it's much more clear what's going on there. I'll try to think of some workaround as well.

kamchatka-volcano added a commit to kamchatka-volcano/nameof that referenced this issue Dec 6, 2022
@kamchatka-volcano
Copy link
Contributor Author

Hi, I think I've found a working solution by using union type as a static member of a class. https://godbolt.org/z/dzKcdfKzP

I opened a PR (#50), please check it out)

@Neargye Neargye closed this as completed in 70ca094 Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants