Skip to content

CWG3202 [basic.fundamental] const std::meta::info is not a reflection #924

Description

@eisenwave

Section: [basic.fundamental]

Issue description

Consider the following example:

constexpr std::meta::info x{};

By definition in [basic.fundamental] p17, a value of type std::meta::info (but not of type const std::meta::info) is a reflection. Since a value of type const std::meta::type is not a reflection, it is unclear how x is meant to represent a null reflection. What is the value of x?

Proposed resolution

Change [basic.fundamental] paragraph 17 as follows:

 A value of type
+cv
 std​::​meta​::​info is called a reflection.
 There exists a unique null reflection;
 every other reflection is a representation of
 - ...

Activity

  1. safocl commented on Jun 18, 2026

    @safocl

    Since a value of type const std::meta::type is not a reflection, it is unclear how x is meant to represent a null reflection. What is the value of x?

    I think that since this exists exclusively at the compilation stage, such a question does not make sense.

    and:

    A reflection is said to represent the corresponding construct.

  2. safocl commented on Jun 18, 2026

    @safocl

    Many other entries in [basic.fundamental] do not specify cv -- does this mean, in your opinion, that const variants are not declared types and their values, and that they must have some other representation than non-const ?

  3. eisenwave commented on Jun 18, 2026

    @eisenwave
    MemberAuthor

    We're very careful to include cv in various places in [basic.fundamental] and to include cv-qualified types in certain categories, like including cv-qualified versions of int in the category of "integral types".

    Since const T is a distinct type from T, some care must be put into making the wording work, and we simply got it wrong for std::meta::info in this place.

  4. safocl commented on Jun 18, 2026

    @safocl

    Since const T is a distinct type from T, some care must be put into making the wording work, and we simply got it wrong for std::meta::info in this place.

    That is, you are now assuming that the formulation allows for the absence of guaranteed equality in values ​​for const and non-const std::meta::info objects?

    constexpr std::meta::info x1{};
    std::meta::info x2{};
    static_assert( x2 == x1 ); //not guaranteed to be "true"

    In this case, wouldn't it be necessary to additionally supplement the provision [expr.eq#6] with the appropriate amendments?

  5. safocl commented on Jun 18, 2026

    @safocl

    Wouldn't it be better then to introduce a general rule for fundamental types, that all provisions also imply cv-qualified entities?

  6. eisenwave commented on Jun 18, 2026

    @eisenwave
    MemberAuthor

    Since const T is a distinct type from T, some care must be put into making the wording work, and we simply got it wrong for std::meta::info in this place.

    That is, you are now assuming that the formulation allows for the absence of guaranteed equality in values ​​for const and non-const std::meta::info objects?

    constexpr std::meta::info x1{};
    std::meta::info x2{};
    static_assert( x2 == x1 ); //not guaranteed to be "true"
    In this case, wouldn't it be necessary to additionally supplement the provision [expr.eq#6] with the appropriate amendments?

    No, because [expr.eq] paragraph 1 states that the lvalue-to-rvalue conversions is applied to operands, which gets rid of these annoying cv qualifications.

    Wouldn't it be better then to introduce a general rule for fundamental types, that all provisions also imply cv-qualified entities?

    I don't know what you mean by that specifically. A lot of things would break if we automatically included cv-qualified types in the category of signed and unsigned integer types for example, and you definitely need to distinguish cv-qualified fundamental types from cv-unqualified types in various places.

  7. safocl commented on Jun 18, 2026

    @safocl

    What is the value of x?

    No, because [expr.eq] paragraph 1 states that the lvalue-to-rvalue conversions is applied to operands, which gets rid of these annoying cv qualifications.

    Doesn't your own words imply that the x object will contain an equivalent value as a non-const object with the same initializer? In that case, I simply don't see any reason for such a question to exist.

  8. eisenwave commented on Jun 18, 2026

    @eisenwave
    MemberAuthor

    What is the value of x?

    No, because [expr.eq] paragraph 1 states that the lvalue-to-rvalue conversions is applied to operands, which gets rid of these annoying cv qualifications.

    Doesn't your own words imply that the x object will contain an equivalent value as a non-const object with the same initializer? In that case, I simply don't see any reason for such a question to exist.

    Just because equality comparison gets rid of cv qualifiers doesn't fix the problem generally.

    If the const object is not a reflection, it's also unclear how lvalue-to-rvalue conversion is supposed to work. Random garbage goes in, reflection comes out, and it's not specified how.

  9. safocl commented on Jun 18, 2026

    @safocl

    If the const object is not a reflection, it's also unclear how lvalue-to-rvalue conversion is supposed to work. Random garbage goes in, reflection comes out, and it's not specified how.

    Here, in my opinion, we're stuck in an infinite recursion loop with my post (#924 (comment)).

  10. eisenwave commented on Jun 18, 2026

    @eisenwave
    MemberAuthor

    Hmm, upon reading a bit further, there is a more fundamental and less obvious question here. Are values ever cv-qualified? What's our model here actually?

    Does a const int x = 0; object store the value "const zero" or just "zero"? It seems like [conv.lval] asssumes that values are never cv-qualified because https://eel.is/c++draft/conv.lval#3.5 doesn't describe any conversion mechanism from a cv-qualified value to the cv-unqualified value.

    So perhaps this issue really is NAD if a const std::meta::info object is considered to hold a value of (cv-unqualified) std::meta::info, but do we actually make it clear that values have no cv-qualifications even if stored in const objects?

    https://eel.is/c++draft/basic.types.general#def:value isn't clear at all about what our model is. A "value" is simply determined by the bits of the value representation, which very well could mean that const int x = 0; has a value representation determining the value "const zero", and int x = 0 has a value representation determining the value "zero".

    I feel like the model of cv-unqualified values makes more sense, but perhaps we should clarify that this is our model by adding something to the definition of values.

  11. frederick-vs-ja commented on Jun 22, 2026

    @frederick-vs-ja

    I feel like that the word "value" used here means some "pure value" that's not associated with certain objects. It might be possible to refer such a value as "prvalue" which automatically has cv-qualification dropped.

  12. katzdm commented on Jun 22, 2026

    @katzdm

    I think my understanding is that the values of "cv T" are those of T if T is scalar, and are distinct if T is a class type. That said, I can't remember whether that idea stems from wording or from "CWG folklore".

  13. jensmaurer commented on Jun 22, 2026

    @jensmaurer
    Member
  14. changed the title [-][basic.fundamental] `const std::meta::info` is not a reflection[/-] [+]CWG3202 [basic.fundamental] `const std::meta::info` is not a reflection[/+] on Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions