I guess static constexpr variables are sometimes useful if allowed in constexpr functions. E.g., implementations of std::visit usually use "virtual function tables" for dynamic dispatch. The vtable variables are constexpr, and it may be better if they inhabit a block scope since they are implementation details.

Constexpr variables are statically initialized, and their destructions are equivalent to no-op, even if non-trivial destructors are involved (since C++20). I don't think allowing them to be defined in constexpr functions is harmful.

IMO static thread_local constexpr variables can also be created in constexpr functions without doing anything bad, since thread local storage is not actually needed to be acquired within constant evaluation. However, they are less worthy than (non-thread-local) usual static constexpr variables, because their addresses are not constant expressions.

Jiang An