【C++ 小问答】3:未定义的 `Constexpr` 函数

下面哪些在编译期报错(非链接期):

  1. 1constexpr int GetVal();
    2constexpr int GetVal() { return 0; }
    3constexpr int i = GetVal();
    
  2. 1constexpr int GetVal();
    2constexpr int i = GetVal();
    
  3. 1constexpr int GetVal();
    2int i = GetVal();
    
  4. 1constexpr int GetVal();
    2constexpr int i = GetVal();
    3constexpr int GetVal() { return 0; }
    

将这几段代码分别用 g++ -c 编译,其中第 2、4 两项都会报如下编译错误:

1./main.cpp:2:25: error: ‘constexpr int GetVal()’ used before its definition
2 constexpr int i = GetVal();
3                   ~~~~~~^~

再用 clang++ -c 编译,第 2、4 两项的编译错误如下:

1./main.cpp:2:15: error: constexpr variable 'i' must be initialized by a constant expression
2constexpr int i = GetVal();
3              ^   ~~~~~~~~
4./main.cpp:2:19: note: undefined function 'GetVal' cannot be used in a constant expression
5constexpr int i = GetVal();
6                  ^

这里关键点有两个:

  1. constexpr 变量必须由常量表达式初始化1
  2. 未定义的 constexpr 函数不被看作一种常量表达式2

第 3 项不会报错,因为普通变量没有上述第一条的限制,而且该样例实际上就是一个使用仅声明了的函数的场景,不要太常见。如果这个函数最终真的没有定义,那也只会报链接错误。


  1. cppreference 对 constexpr 变量的描述 :“A constexpr variable must satisfy the following requirements: … the full-expression of its initialization, including all implicit conversions, constructors calls, etc, must be a constant expression." ↩︎

  2. cppreference 对常量表达式的描述 :“A core constant expression is any expression whose evaluation would not evaluate any one of the following: … a function call to a constexpr function which is declared, but not defined; …” ↩︎


【C++ 小问答】2:平台对隐式类型转换的影响
打印 C++ 类的内存排布