Skip to content

[dcl.constinit] p1 "Declaration of a variable" is broken wording #6523

Open
@Eisenwave

Description

@Eisenwave
Member

The constinit specifier shall be applied only to a declaration of a variable with static or thread storage duration.

- [dcl.constinit] p1

This is broken wording because [basic.pre] says:

A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
The variable's name, if any, denotes the reference or object.

What the former paragraph says is thus:

The constinit specifier shall be applied only to a declaration of a declaration of an object or reference other than a non-static data member or of an object, with static or thread storage duration.

Inlining the definition gives us "declaration of a declaration" which is either meaningless or recursive.

Suggested Fix

Extend [basic.pre] p6 as follows:

 A *variable* is introduced by the declaration of a reference
 other than a non-static data member or of an object.
 The variable's name, if any, denotes the reference or object.
+Such a declaration is called *variable declaration*.

Then, in the entire document:

-declaration of a variable
+variable declaration

Activity

Eisenwave

Eisenwave commented on Aug 27, 2023

@Eisenwave
MemberAuthor

Actually this wording issue extends beyond that; there are 11 uses of "declaration of a variable" in the standard right now.

JohelEGP

JohelEGP commented on Aug 27, 2023

@JohelEGP
Contributor

Inlining the definition gives us "declaration of a declaration" which is either meaningless or recursive.

I think this is wrong.
A variable is not a declaration.
It is introduced by a declaration.

Eisenwave

Eisenwave commented on Aug 27, 2023

@Eisenwave
MemberAuthor

A variable is not a declaration.
It is introduced by a declaration.

Honestly that might make the wording issue even more severe, because it's unclear what a variable even is. In the declaration int x, a variable is introduced ... but what exactly is the variable?

The variable isn't the thing which is declared (the object or reference is) for sure, so declaration of a variable is meaningless wording. When we say that "constinit applies to the declaration of a variable",

  • either the wording is redundant because it applies to the declaration of a declaration, or
  • it is meaningless, because a variable is just "some thing", and the semantics of constinit on "some thing" are not defined.
JohelEGP

JohelEGP commented on Aug 27, 2023

@JohelEGP
Contributor

that might make the wording issue even more severe

I'm not suggesting a change here.
Just pointing out that variable isn't defined to be a declaration.
But alluding to its definition as a term, that it is introduced by one.
So I think that your argument I quoted is wrong, even if the other parts of the issue aren't.

jensmaurer

jensmaurer commented on Aug 27, 2023

@jensmaurer
Member

We have a long-standing problem with the wording around "variable" that some variables can denote different objects at different times.

For example, `thread_local int x;" denotes a different object in each thread.
A local variable "int y;" denotes a different object in each (possibly recursive) invocation.

I don't think the cosmetic adjustment from "declaration of a variable" to "variable declaration" is worth the bother, but anyone tackling the full problem (see above) is most welcome to do so; probably that should be in the form of a paper.

RealLitb

RealLitb commented on Sep 4, 2023

@RealLitb

Please bear with me, but I can't help but think that "variable" is missing from the list of things that are entities. Entities are said to be "introduced" by declarations. And so are variables. And things far away from [basic] treat variables as if they were entities. For example https://eel.is/c++draft/expr.prim.id#unqual-3

The result is the entity denoted by the unqualified-id ([basic.lookup.unqual]).
If the unqualified-id appears in a lambda-expression at program point P and the entity is a local entity ([basic.pre]) or a variable declared by ...

The expression is an xvalue if it is move-eligible (see below); an lvalue if the entity is a function, variable, structured binding, data member, or template parameter object; and a prvalue otherwise ([basic.lval]); it is a bit-field if the identifier designates a bit-field.

Even the text directly surrounding the definition of "entity" and "variable" is difficult to parse without "variable" being an entity itself. It was there in the list in the past, but why was it removed?

AlisdairM

AlisdairM commented on Sep 5, 2023

@AlisdairM
Contributor

I remember filing an NB comment or Core issue on this around C++11 FDIS time. The omission of variable from the list of entities was entirely intentional at the time, and there were concerns that adding variable to the list of entities would have unforeseen side effects.

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

        Participants

        @AlisdairM@RealLitb@JohelEGP@Eisenwave@jensmaurer

        Issue actions

          [dcl.constinit] p1 "Declaration of a variable" is broken wording · Issue #6523 · cplusplus/draft