Hacker News new | ask | show | jobs
by kazinator 338 days ago
The way block scope statics are handled in C++ is a mistake. Block scope statics that don't depend on any non-static local variables should be initialized when the program starts up. E.g.:

  void fun(int arg)
  {
     static obj foo(arg);   // delayed until function called (dependency on arg)
     static obj bar();      // inited at program start (no dependency on arg)
  }
In other words, any static that can be inited at program startup should be, leaving only the troublesome cases that depend on run-time context.
3 comments

In theory I agree, but in practice this just increases compile time by a lot, and we need to be able to manually toggle the code that gets executed at compile time.
What?

Edit: what?

When every eligible piece of code becomes automatically constexpr, as you suggest, the compile time will just balloon. The code still needs to be compiled and executed, just all at once now. Optimization is one of those annoying problems for which we currently don't have the compute to fully bruteforce it. We need to be selective with which code is marked constexpr.
> constexpr, as you suggest

I made no mention of constexpr.

Program start-up isn't compile time.

The idea is that since "static obj bar()" doesn't depend on anything in the function, it could in principle be moved outside of the function. So in actual fact, it can be treated that way by the loading semantics of the program (can be constructed without the function having to be called), except that the name bar is only visible inside the function.

I don't understand why C++ wouldn't have specified it this way going back to 1998, but that's just me.

I think that would cause some surprising behavior changes for certain code changes, not something that C++ (or any language) needs more of.
Which is why it should have been sorted out decades ago.
I mean when making (apparently) small changes to the initialization of the static even in the proposed new system.
Why not just use constexpr in the second case?
What if the object is to be mutable?
You use constinit. But this means constexpr constructor (easy with 2-phase init, not too much of a problem for singleton objects), and trivial destruction
Does that guarantee that the static object is constructed before the first execution of the block?
Yes, it will be constructed at compile time. Not everything can be constinit.