1

I get the following error in my project upon compiling. Tried everything but unable to resolve this.

Reproduced the error here: https://replit.com/join/egfoiwpgig-darshanpandhi

Error

error: constexpr variable 'noOfTiles' must be initialized by a constant expression

Relevant Code

Board.h

# pragma once

class Board {
private:

public:
    static constexpr int getTotalNoOfTiles();
};

Board.cpp

# include "Board.h"


constexpr int Board::getTotalNoOfTiles() {
    return 21;  // calculation simplified for the sake of example
}

Player.h

# pragma once

# include "Board.h"


class Player {
private:
    static constexpr int noOfTiles = Board::getTotalNoOfTiles();   // this needs to be constexpr because I will be using noOfTiles as an array size in this same file
};


Question

Isn't Board::getTotalNoOfTiles() a constant expression since it simply returns 21. Isn't this a compile-time constant?

Reproduced the error here: https://replit.com/join/egfoiwpgig-darshanpandhi

  • 1
    Can you explain how a translation unit that includes only the header file could possibly know what the constant value is? `static constexpr int getTotalNoOfTiles();` is all that the compiler sees, in the header file, what constant integer value would the compiler have, at this point? – Sam Varshavchik Aug 31 '23 at 01:50
  • I recently came across `constexpr` but I thought since getTotalNoOfTiles() is defined as constexpr, that should be enough for the compiler to understand that it shall be a constant – GAMERZNIGHTMARE Aug 31 '23 at 02:07
  • 1
    Actually constexpr only allows a function to be constant evaluated. It can also be called at runtime. And to be constant evaluated at compile time, it must be in the same translation unit as @SamVarshavchik noted – doug Aug 31 '23 at 02:11
  • `constexpr` is not `consteval`. Look them up at cppreference.com for the details. – Jesper Juhl Aug 31 '23 at 06:04
  • It is not enough "to understand that it shall be a constant". In order to be a constant ***expression***, it is also necessary to "understand" what the actual value is. Is it 42? Is it 0? Is it -15? If a compiler only includes the header file and sees the declaration, this is unknown, and `getTotalNoOfTiles()` cannot be used in a constant expression. – Sam Varshavchik Aug 31 '23 at 10:56

1 Answers1

3

The definition of a constexpr function, just like a inline function which it implies, belongs into the header, not in a .cpp file, at least if it is supposed to be used in other translation units.

In this case, either define it directly in the class definition or put the definition after the class definition in the header file.

Without that the definition of the function would also not be visible to the compiler when compiling the call in the other translation unit, so it couldn't possibly make use of it at compile-time, i.e. in a constant expression.

user17732522
  • 53,019
  • 2
  • 56
  • 105