Clang error: in-class initializer for static data member is not a constant expression (err_in_class_initializer_non_constant)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: in-class initializer for static data member is not a constant expression
Type Error
Category Semantic Issue
Internal Id err_in_class_initializer_non_constant
Internal Message in-class initializer for static data member is not a constant expression
Regular Expression (?:error|fatal error)\: in\-class initializer for static data member is not a constant expression
First Commit 2009-03-14 5a8987ca5113 Update tablegen diagnostic files to be in sync with the def files.

Description

The error is issued by the Clang compiler when an attempt is made to initialize a static data member inside a class definition with a value that is not a constant expression. In C++, static data members must be initialized with constant expressions, which are evaluated at compile time. This requirement ensures that the initializer can be stored in the read-only section of memory and shared among all instances of the class. The error commonly arises when the initializer expression involves function calls, non-constant expressions, or any operation that cannot be resolved to a constant value at compile time.  
AI Generated

Example

In the following example, a function f() is defined which returns an integer value. Then, a structure S is declared that contains a static data member v. The member v attempts to be initialized with the return value of the function f(). However, this initialization causes a compile-time error because the initializer for a static data member must be a constant expression. The function call to f() does not satisfy this requirement, as the value it returns cannot be evaluated at compile time, leading to the error message indicating that the in-class initializer for the static data member is not a constant expression.  
AI Generated


Flags -xc++

[Try out in Compiler Explorer]

Source
int f() { return 5; }

struct S { static const int v = f(); // v initializer is not constant
};
Compiler Output
<source>:3:33: error: in-class initializer for static data member is not a constant expression


Clang Internals (17.0.6)

Git Commit Message

Update tablegen diagnostic files to be in sync with the def files.

llvm-svn: 67004

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaDecl.cpp (line 13503)

/// AddInitializerToDecl - Adds the initializer Init to the
/// declaration dcl. If DirectInit is true, this is C++ direct
/// initialization rather than copy initialization.
void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
  // ...
  if (VDecl->isLocalVarDecl()) {
  // ...
  } else if (VDecl->isStaticDataMember() && !VDecl->isInline() && VDecl->getLexicalDeclContext()->isRecord()) {
    // ...
    // Do nothing on dependent types.
    if (DclT->isDependentType()) {
    // ...
    } else if (VDecl->isConstexpr()) {
    // ...
    } else if (!DclT.isConstQualified()) {
    // ...
    } else if (DclT->isIntegralOrEnumerationType()) {
      // ...
      if (getLangOpts().CPlusPlus11 && DclT.isVolatileQualified())
      // ...
      else if (Init->isValueDependent())
      // ...
      else if (Init->isIntegerConstantExpr(Context, &Loc))
      // ...
      else if (Init->getType()->isScopedEnumeralType() && Init->isCXX11ConstantExpr(Context))
      // ...
      else if (Init->isEvaluatable(Context)) {
      // ...
      } else {
        // ...
        Diag(Loc, diag::err_in_class_initializer_non_constant) << Init->getSourceRange();

clang/lib/Sema/SemaDecl.cpp (line 13524)

/// AddInitializerToDecl - Adds the initializer Init to the
/// declaration dcl. If DirectInit is true, this is C++ direct
/// initialization rather than copy initialization.
void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
  // ...
  if (VDecl->isLocalVarDecl()) {
  // ...
  } else if (VDecl->isStaticDataMember() && !VDecl->isInline() && VDecl->getLexicalDeclContext()->isRecord()) {
    // ...
    // Do nothing on dependent types.
    if (DclT->isDependentType()) {
    // ...
    } else if (VDecl->isConstexpr()) {
    // ...
    } else if (!DclT.isConstQualified()) {
    // ...
    } else if (DclT->isIntegralOrEnumerationType()) {
    // ...
    } else if (DclT->isFloatingType()) { // also permits complex, which is ok
      // In C++98, this is a GNU extension. In C++11, it is not, but we support
      // it anyway and provide a fixit to add the 'constexpr'.
      if (getLangOpts().CPlusPlus11) {
      // ...
      } else {
        // ...
        if (!Init->isValueDependent() && !Init->isEvaluatable(Context)) {
          Diag(Init->getExprLoc(), diag::err_in_class_initializer_non_constant) << Init->getSourceRange();

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/SemaCXX/cxx0x-class.cpp

  • clang/test/SemaCXX/cxx0x-class.cpp:14:26: error: in-class initializer for static data member is not a constant expression