請參閱更新以獲得更好的問題示例。原代碼有哪些muddies圖片問題的混合:gcc是否考慮將非常量表達式函數的內置函數作爲常量表達式
這個問題Why can I call a non-constexpr function inside a constexpr function?呈現以下代碼
#include <stdio.h>
constexpr int f()
{
return printf("a side effect!\n");
}
int main()
{
char a[f()];
printf("%zd\n", sizeof a);
}
這是我的回答是形成不良但gcc 4.8.2
允許它(see it live )。
但是,如果我們使用標誌gcc
產生一個錯誤(see it live):
error: call to non-constexpr function 'int printf(const char*, ...)'
return printf("a side effect!\n");
^
所以seems
該gcc
正在考慮的printf
內置版本是一個常量表達式。 gcc
documents builtins here但是沒有記錄這種情況,其中非constexpr函數的內建可以被認爲是一個常量表達式。
如果事實確實如此:
- 是一個編譯器允許這樣做嗎?
- 如果他們被允許,他們不需要證明它符合?
- 可以這樣考慮的延伸,如果是這樣,好像這將需要警告的C++ draft standard部分
1.4
實現達標款說(重點煤礦):
A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.
更新
正如凱西指出有一些事情正在進行在原來的問題,使其成爲一個不好的例子。一個簡單的例子將使用std::pow其不是constexpr功能:
#include <cmath>
#include <cstdio>
constexpr double f()
{
return std::pow(2.0, 2.0) ;
}
int main()
{
constexpr double x = f() ;
printf("%f\n", x) ;
}
編譯並沒有警告或錯誤(see it live)構建但添加使得它產生一個錯誤(see it live)。注:why math functions are not constexpr in C++11:
error: call to non-constexpr function 'double pow(double, double)'
return std::pow(2.0, 2.0) ;
^
究竟你認爲GCC違反了這裏?是不是[dcl.constexpr]/5「對於一個constexpr函數,如果沒有函數參數值存在,使得函數調用替換會產生一個常量表達式(5.19),則該程序不合格;不需要診斷。 ? – dyp
注意:我不太明白gcc拒絕它時爲什麼說「gcc 4.8.2允許它」,調用'f()'是*不是一個常量表達式*。然而,它不拒絕的是函數f'本身的定義,對此AFAIK,不需要診斷。 – dyp
我不相信它將內置視爲一個常量表達式。你沒有提供證明它的例子(並且調用'f()',導致調用'printf(「副作用!\ n」)*不*被認爲是一個常量表達式)。 – dyp