【问题标题】:Reinterpret cast a template non-type parameter: clang c++14 vs c++1z重新解释强制转换模板非类型参数:clang c++14 vs c++1z
【发布时间】:2016-09-15 06:13:04
【问题描述】:

考虑以下代码:

template <int* > struct foo { };

int main() {
    foo<(int*)42> f;
    (void)f;
}

当使用-std=c++11-std=c++14 在clang 3.8.0 上编译时,程序会编译。使用-std=c++1z 编译时,出现以下错误:

main.cpp:4:9: error: non-type template argument is not a constant expression
    foo<(int*)42> f;
        ^~~~~~~~

无论 C++ 模式如何,gcc 5.3.0 都不会编译代码,我认为这是正确的。 C++14 和 C++1z 之间的 clang 有什么区别,为什么它接受代码?与此处相关的 C++1z 中是否发生了一些变化?

【问题讨论】:

  • 附带说明,VS 2015 编译得很好
  • 显然是一个错误。 C++1z 放松了对非类型模板参数的约束,因此可能使用了不同的代码路径(不会触发错误)。
  • 它显然被视为空指针:coliru.stacked-crooked.com/a/966a61826b6d73f9。这不是理智的行为。
  • @T.C.,是什么让你认为这是可能的?
  • @Rakete1111 以什么方式编译上述代码最好描述为“很好”。

标签: c++ clang c++14 c++17


【解决方案1】:

使用godbolt 表明在-std=c++1z 模式下,Clang 3.5.1 接受代码,但 3.6.0 拒绝它。 changelog 表示此版本是在添加对 C++1z 功能的支持时添加的,即“对所有非类型模板参数的持续评估”。我的猜测是 C++11 和 C++14 模式使用 C++11 规则,而 C++1z 模式使用 C++1z/最新草案规则。当然,程序在 C++11/14 模式下被认为是有效的事实本身就是一个错误。

以下是一些具有类似(但不直接相关)案例的错误报告:

Bug 18043 - allow arbitrary address constant expressions as non-type template arguments as an extension

Bug 10398 - Clang won't accept a null pointer constant as a non-type template argument

Bug 10396 - clang crashes during name mangling with as non-type template parameter

Bug 9700 - Null pointer not accepted as non-type template argument

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多