该计划是不规范的并且不需要根据以下诊断C++11 标准草案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf部分7.1.5
constexpr 说明符段落5其中说:
对于 constexpr 函数,如果不存在这样的函数参数值
函数调用替换会产生一个常量
表达式(5.19),程序格式错误;无需诊断。
并提供以下示例:
constexpr int f(bool b)
{ return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required
和部分5.19
段落2 says:
条件表达式是核心常量表达式,除非它
涉及以下内容之一作为潜在评估的子表达式
[...]
包括:
— 调用除 constexpr 构造函数之外的函数
文字类或 constexpr 函数 [注意:重载解析
(13.3)照常应用——尾注];
在这种情况下,我们可能更喜欢进行诊断,这可能只是一个疏忽,我有一个类似情况的错误报告,其中gcc
不会产生错误,但我们可能希望它:编译器在常量表达式中认为未定义的行为是否允许有余地? https://stackoverflow.com/questions/21502017/is-the-compiler-allowed-leeway-in-what-it-considers-undefined-behavior-in-a-cons.
Update
使用-fno-builtin
标志将导致gcc
产生以下错误:
error: call to non-constexpr function 'int printf(const char*, ...)'
return printf("a side effect!\n");
^
So gcc
确实考虑到这一点不规范的当它使用内置版本时它只是忽略它printf
.
虽然使用起来有些不一致-pedantic
产生以下警告:
warning: ISO C++ forbids variable length array 'a' [-Wvla]
char a[f()];
^
请注意,使用f()
初始化一个常量表达式多变的:
constexpr int x = f() ;
确实会产生错误:
error: 'printf(((const char*)"a side effect!\012"))' is not a constant expression
请注意,另外在更一般的情况下,不允许编译器将标准库函数标记为常量表达式 除非标准明确允许 https://stackoverflow.com/q/27744079/1708801.