2

c23 added the constexpr keyword to the standard, which seems to me to be quite puzzling.

I understand that the appeal would be that constexpr objects evaluate to constant expressions, whereas static const objects do not. My question is why don't they? To my understanding static const objects must be initialized with a constant expression anyway, why not just change the behavior of static const objects to evaluate to constant expressions?

2
  • Basically because 1) there are "C++ people" in the C committee 2) and while "C++ people" wants C to become C++, there are those who don't want C to adopt C++'s static initialization order fiasco 3) but the fiasco is already there in C in the form of a bad loophole in the definition of constant expressions which said "An implementation may accept other forms of constant expressions" leaving initialization from constant expressions open to compiler abuse. Commented Mar 4 at 9:43
  • C23 didn't fix this loophole but left it open with a different wording. And compilers already implements this as they please since chapter 6.6 was bleak before C23 and remains bleak after 6.6. As a result, C code using constant expressions during initialization may be non-portable. For example it is non-portable between different versions of gcc even though the C standard wording between those versions didn't change. Commented Mar 4 at 9:45

1 Answer 1

4

static const vs contexpr in c23: what's the point?

Pragmatically, I see little point to C23 constexpr in general, other than to make C slightly more source-compatible with C++ than previous versions were.

I understand that the appeal would be that constexpr objects evaluate to constant expressions,

Yes, and that makes constexpr objects a bit of a convenience feature, especially for people who look down their noses at macros. But there are also one or two other meaningful differences, which may have played a role in getting constexpr accepted.

whereas static const objects do not. My question is why don't they? To my understanding static const objects must be initialized with a constant expression anyway, why not just change the behavior of static const objects to evaluate to constant expressions?

In C, const is a type qualifier, whereas constexpr is a storage class specifier, notwithstanding that it implies const type. On the other hand, constexpr does not imply static storage duration. constexpr objects defined at file scope have static storage duration by virtue of that placement, but those declared at block scope have automatic duration unless also declared static. I am in no way suggesting that this is enough of a distinction to justify adding constexpr, but I do want you to recognize that constexpr to static const is, in general, an apples to oranges comparison.

Ultimately, it comes down to the committee's choices. I have no special insight into the committee's decisions, but these are some of the relevant priorities that I impute to it:

  • to prefer convergence toward C++ over divergence from it
  • to make C language features as orthogonal as possible

The committee having taken it in mind to add to C objects whose identifiers are considered constant expressions, both of those priorities favor doing it by adding constexpr over doing it by changing the semantics of const.

However, the main new thing that constexpr brings to C may be this:

NOTE 2 The constraints for constexpr objects are intended to enforce checks for portability at translation time.

(C23 6.7.2/18)

The main relevant constraint seems to be:

The value of any constant expressions or of any character in a string literal of the initializer shall be exactly representable in the corresponding target type; no change of value shall be applied.

(C23 6.7.2/5)

The spec gives several examples of definitions of constexpr objects that violate that constraint, where there would be no constraint violation if constexpr were changed to const. Basically, constexpr provides compile-time range and precision validation of the initial value with respect to the object's type.

There are a handful of other, minor, differences from const, but all of them are secondary to the choice to provide constexpr in some form at all.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.