【发布时间】:2016-09-11 20:12:45
【问题描述】:
我有以下代码可以在较旧的 gcc 上编译,但不能在版本 6 上编译(与 -std=c++1z 一起使用)。 Clang 也拒绝它,说对象 val 没有正确的链接。我不明白其中的区别。指针类型的 constexpr 变量不应该或多或少透明地工作吗?我在语法中是否缺少一些允许它工作的东西?还是这违反了标准的某些部分?
typedef void(*t_voidfn)();
template <t_voidfn> struct s {};
void fn() {
static constexpr t_voidfn val = &fn;
s<val> x;
}
另一方面,这个可行。
typedef void(*t_voidfn)();
template <t_voidfn> struct s {};
void fn() {
s<&fn> x;
}
【问题讨论】:
-
那里的静态关键字不会使变量成为私有变量,它使它成为具有持久存储的运行时值,在第一次调用函数时被初始化...
-
@KerrekSB 但我没有获取变量的地址,我使用的是它的值,它在编译时初始化为具有明显可接受链接的东西的地址,因为值本身工作。
-
错误信息不是很有帮助。也就是说,函数的地址必须严格表示为
&fn或fn。这只是 C++14 及以下标准中指定的限制,C++17 取消了该限制。这就是代码在 C++1z 模式下在两个编译器上编译的原因。抄送@KerrekSB -
@bogdan 是明确要求此限制还是在 c++17 之前未指定。我问的原因是 gcc-4.8.5 和 gcc-5.3.0 接受代码为有效。或者这是在 gcc-6 中修复的 gcc 中的错误?
-
@bogdan 我认为您应该写一个答案,以便我接受。我希望能提供一些关于标准在 c++11、14、17 中的内容以及它如何变化的额外信息。无论如何谢谢。