Open zygoloid opened 11 months ago
The aforementioned bugzilla thread was intended to point out that some standard-compliant code is currently rejected by gcc. Namely, this code was supposed to work:
template <auto O>
struct B {
static constexpr int off = O();
};
struct A {
char a;
B<[]() static constexpr ->int { return offsetof(A, b); }> b;
};
due to [class.mem.general]/7.1 (function body) + note4 for closure sub-class.
The suggested resolution should be to explicitly list "closure type" in "Note 4", rather than to rephrase and exclude the "closure type" from a "complete class context" candidates.
@stsp: No, not as a core issue. Please write a paper targeted at EWG if you wish to extend the complete-class contexts; there are non-trivial implementation concerns.
CWG2852
@jensmaurer Well, all I need is to use offsetof() in templates. If you tell me how to do that, I won't need to write any EWG paper. But so far, every once I find a way to do that, it immediately gets disallowed. First one was reinterpret_cast in constexpr, which could trivially be used to calc an offset - disallowed, even if it actually worked and my code was using it. Lambdas in class-complete context - disallowed. Come one, just tell me how to use offsetof() then... Don't only disallow, give me a work-around!
EWG is the right group to discuss extensions to the language, not this forum. Side note: CWG2784 discusses an issue with interpreting the term "member-designator" from C's specification of "offsetof" in a C++ context.
@stsp Instead of adding another complete-class context, you can make the class type dependent and defer performing instantiation until the class is complete: https://godbolt.org/z/sjbKGnqva
(This is off-topic for this forum, but hopefully this example can save you and EWG some time.)
That works, thank you! Just a few minor downsides:
But its a working solution.
Full name of submitter (unless configured in github; will be published with the issue): Richard Smith
Reference (section label): [class.mem.general]/7
Link to reflector thread (if any): None, but GCC bugzilla thread: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923
Issue description:
[class.mem.general]/7 is overly broad:
The "within" here appears to cover such things appearing indirectly within the member-specification, such as a default argument or default template argument of a class-scope lambda-expression:
Similarly, the current rule appears to treat noexcept-specifiers and default arguments appearing as part of all function types in the class body as complete-class context, rather than only those introduced in the declaration of a member or friend function:
Suggested resolution:
Change in [class.mem.general]/7: