C++ Logo

sg20

Advanced search

Re: [SG20] "constinit" seems to be very confusing

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 22 Nov 2020 21:00:38 -0500
Hi Nico,

FWIW, I agree with Barry Revzin and Tomasz Kaminski on the obvious
etymology of "constinit".
And I agree with Balog Pal: "constinit" is definitely the *easiest* to
teach out of all these keywords!

`constinit` is simple and regular:
    constinit int x = foo();
means no more and no less than
    int x = foo();
with the additional information that the initialization must happen at
compile-time, not at runtime. In a perfect world, it would have been an
attribute, since it has no effect on the type system. (But we're hung up on
the ignorable attributes rule
<https://quuxplusone.github.io/blog/2018/05/15/the-ignorable-attributes-rule/>
.)

The next easiest keyword to teach is `const`.
    const int *p;
means "a pointer to an int, *which int I promise not to modify*." `const`
participates in the type system just enough to enforce "contract law"
around that promise and prevent the programmer from breaking their promise
without an explicit cast.
The first unfortunate historical weirdness of `const` is that
    const int x = 42;
at global scope defines a global variable *with internal linkage*; i.e.,
`const` has one essentially random effect on linkage as well as its
type-system effect.
The second unfortunate historical weirdness is that const variables of
integral types are sometimes treated as constexpr, e.g.
    const int x = 42;
    int a[x];
compiles even though
    const int y = foo();
    int a[y];
doesn't. But this weirdness hardly matters, since modern code will use
`constexpr` when it means `constexpr`. (For an example of where it can
matter, see "Why do I get a linker error with static const and value_or?".
<https://quuxplusone.github.io/blog/2020/09/19/value-or-pitfall/>)
A third weirdness is that `const T&` can bind to rvalues as well as
lvalues; but that tidbit should be taught alongside rvalues, not alongside
`const` itself.

Then there's `constexpr`. It's hard mainly because `constexpr` on a
function means "maybe constexpr," but `constexpr` on a variable means "must
be constexpr." I think in general it's getting easier to teach, as more of
the language becomes constexpr-friendly.
That leaves `consteval`, which is new in C++20 and I haven't learned much
of anything about it yet.

HTH,
Arthur


On Sun, Nov 22, 2020 at 10:07 AM Nicolai Josuttis via SG20 <
sg20_at_[hidden]> wrote:

> Starting to learn and document C++20, I just realized that
> the keyword "constinit" seems very confusing.
> Every naive programmer would assume it means "init a const",
> but it seems the const is simply wrong; it is the opposite.
> Or as Jonathan Müller wrote in a talk:
> constinit = constexpr - const
>
> Now I wonder how to teach that.
> Could somebody elaborate please why we have chosen this name
> and what is the best way to make this name plausible to ordinary
> programmers?
>
> Thanks
> Nico
>

Received on 2020-11-22 20:00:51