constexpr(但不是真正的)构造函数在GCC中编译,而不是在Clang中编译
constexpr (but not really) constructor compiles in gcc but not in clang
我正在与C 14及以上的constexpr
构造函数一起玩,并注意到一些奇怪的东西。这是我的代码:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
#define PFN(x) cout << x << __PRETTY_FUNCTION__ << endl
#define PF PFN("")
#define NL cout << endl
struct A {
constexpr A() { PF; }
virtual ~A() { PF; NL; }
};
struct B : A {
constexpr B() { PFN(" "); }
virtual ~B() { PFN(" "); }
};
int main(int argc, char** argv) {
{ A a; }
{ B b; }
A* a = new B;
delete a;
return 0;
}
简单的例子。我用g++ -std=c++14 -o cx_test cx_test.cpp
编译了它,期望它给我一个编译错误(因为我使用cout
和流操作员打印函数的名称。但是,令我惊讶的是,它会编译!当我运行它时,它给出了以下输出:
$> g++ -std=c++14 -o cx_test cx_test.cpp && ./cx_test
constexpr A::A()
virtual A::~A()
constexpr A::A()
constexpr B::B()
virtual B::~B()
virtual A::~A()
constexpr A::A()
constexpr B::B()
virtual B::~B()
virtual A::~A()
$>
但是,当我与Clang编译时,我得到:
$> clang++ -std=c++14 -o cx_test cx_test.cpp && ./cx_test
cx_test.cpp:12:15: error: constexpr constructor never produces a constant expression [-Winvalid-constexpr]
constexpr A() { PF; }
^
cx_test.cpp:12:21: note: non-constexpr function 'operator<<<std::char_traits<char> >' cannot be used in a constant expression
constexpr A() { PF; }
^
cx_test.cpp:9:12: note: expanded from macro 'PF'
#define PF PFN("")
^
cx_test.cpp:8:26: note: expanded from macro 'PFN'
#define PFN(x) cout << x << __PRETTY_FUNCTION__ << endl
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/ostream:556:5: note: declared here
operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
^
1 error generated.
$>
这似乎是G 的错误,因为构造函数似乎违反了constexpr
的限制,但我不太确定。哪个编译器正确?
这是G 版本,这是Clang版本(在IDEONE上(。
gcc和clang都是正确的,您的程序不需要诊断,因为没有办法调用构造函数,以便可以将它们作为核心的子表达进行评估恒定表达。
来自[dcl.constexpr] p5:
对于非template,非默认的constexpr函数或 非template,非违约,非属性constexpr构造函数,如果 没有参数值,以至于函数的调用或 构造函数可能是核心常数的评估子表达 表达式([Expr.const](,程序不明显;没有诊断 必需的。[示例:
constexpr int f(bool b) { return b ? throw 0 : 0; } // OK constexpr int f() { return f(true); } // ill-formed, no diagnostic required struct B { constexpr B(int x) : i(0) { } // x is unused int i; }; int global; struct D : B { constexpr D() : B(global) { } // ill-formed, no diagnostic required // lvalue-to-rvalue conversion on non-constant global };
- 结束示例]
如果我们强迫要在恒定表达上下文中评估的构造函数,那么您也将从GCC中获得诊断(请参阅IT LIVE(:
{ constexpr A a; }
相关文章:
- 为什么 gcc 编译这个而 msvc 没有
- std::unique_ptr 在 GCC 中工作,但不能在 Visual Studio 中编译
- GCC,CMake,预编译标头和维护依赖项
- GCC 8.3 无法编译 std::bind_front
- Clang不会编译GCC会编译的模板专业化
- 使用交叉工具ng编译gcc时出错
- 编译 GCC-5.0 OS X 狮子 dyld:找不到符号:__ZNKSt11logic_error4whatEv
- 在类中将不完整类型的unique_ptr初始化为 nullptr 时编译 gcc 错误
- 除了 Linux 上的源代码和编译 (GCC) 之外,有没有办法在 Windows 中托管 IDE
- 在 64 位 debian 上编译 GCC 的代码可视化补丁
- 编译gcc 4.6.4中的boost::move
- 模板编译:gcc vs VS2010
- C++ 使用编译器编译"gcc"简单文件
- 如何从php编译GCC
- 在 Visual Studio 中编译 gcc 代码会导致错误 C3646:"__attribute__":未知的覆盖说明符
- 在windows上编译gcc 4.7
- 在Vortex86DX上从头开始构建和编译GCC 5.2.0时出错
- 在编译GCC时出错部分模板专门化,而不是MSVC
- GLM Math lib 编译 GCC 错误
- Synology交叉编译GCC -std=c++0x