Yeah, agreed; I'd really like to avoid any design that requires us to defer
these decisions to the end of the TU; I suspect we'll find that brittle and
with tough corner cases (not to mention the implementation complexity).

I guess it isn't even the dereference that's the problem, but the
value-to-rvalue conversation on the resulting lvalue, right? If so, I think
that would be okay: such an lvalue-to-rvalue conversion would still be
immediate-escalating by virtue of being an expression of consteval-only
type ([expr.const]/24.3), which coincides with when a complete type would
be required. What do you think?

(I did see the CWG issue; thanks for opening! I sometimes like to discuss
these things a bit off-thread before engaging Core, just to get my thoughts
together)

On Mon, Jan 19, 2026, 10:11 AM Jakub Jelinek <[email protected]> wrote:

> On Mon, Jan 19, 2026 at 09:42:05AM -0500, Daniel Katz wrote:
> > Thanks for raising this issue, Jakub.
> >
> > I'm going to circle back with my coauthors regarding rationale for
> > extending consteval-only-ness to pointers and references.
> >
> > If such types weren't consteval-only, do you think that would be
> sufficient
> > to solve the issue? Any concerns that come to mind with that approach
> > (e.g., ways that it would allow meta::info to leak to anytime)?
>
> I've filed https://github.com/cplusplus/CWG/issues/836 so it can be
> discussed further there (though perhaps I should have included there more
> details).
> If e.g. pointers to consteval-only aren't consteval-only (or perhaps they
> are treated that way from within class non-static data members but not
> otherwise), then the question is how to arrange after
> struct A;
> A *p;
> struct A { std::meta::info a; };
> not emitting runtime code which dereferences *p, it is fine to emit such a
> pointer into the compiled code, it has well defined size etc.  But one
> better wouldn't dereference such pointer (which it can't be dereferenced
> before the class is complete, and can't be dereferenced in constant
> evaluated code because the var is not constexpr).
> From the implementation POV, I think it would be easier if we could decide
> if a class is consteval-only or not at the class definition time rather
> than
> having to defer all the consteval-only related decisions until end of TU,
> whether it is just non-static data members in there with consteval-only
> class types / std::meta::info or pointers/references/array/function types
> to those too (for references I guess the referenced type
> needs to be complete at least in the NSDMs, but in function types one can
> have references to incomplete types:
> struct S;
> struct T { int (*p) (S &); };
> ).  Though it would be really complicated if we had say consteval-only vs.
> non-consteval-only pointers to the same class and had to treat them
> differently (non-consteval-only e.g. ones parsed when the pointed type
> was still incomplete and consteval-only when it was complete and determined
> to be consteval-only).
>
>         Jakub
>
>

Reply via email to