c – “if constexpr”与“尝试constexpr功能”警告交互

我声称 this program应该是格式良好的:它声明了S< int>的constexpr成员函数.但是,GCC和Clang都拒绝这个计划.
template<class T>
struct S {
    constexpr int foo() {
        if constexpr (std::is_same_v<T,int>) {
            return 0;
        } else {
            try {} catch (...) {}
            return 1;
        }
    }
};

int main()
{
    S<int> s;
    return s.foo();  // expect "return 0"
}

GCC说:

error: ‘try’ in ‘constexpr’ function

Clang说:

error: statement not allowed in constexpr function

他们似乎都没有注意到“try”语句位于if constexpr语句的废弃分支中.

如果我将try / catch输出到非constexpr成员函数void trycatch()中,那么Clang和GCC都会再次对代码感到满意,即使它的行为应该等同于不满意的版本.

template<class T>
struct S {
    void trycatch() {
        try {} catch (...) {}
    }
    constexpr int foo() {
        if constexpr (std::is_same_v<T,int>) {
            return 0;
        } else {
            trycatch();  // This is fine.
            return 1;
        }
    }
};

这是

> GCC和Clang都有一个错误?
>标准中的缺陷,GCC和Clang是否忠实地实施?
>由于foo()的“conditional constexprness”引起的实施质量问题?

(不相关的背景:我正在为任何分配器感知版本的任何:: emplace< T>()实现constexpr,其分配器可能是constexpr-per-P0639(即它可能缺少deallocate成员函数)或者可能没有.前一种情况我们不想要或不需要尝试;在后一种情况下我们需要尝试以便在T的构造函数抛出时调用deallocate.)

解决方法

编制者遵守标准. C 17草案N4659说([dcl.constexpr] /(3.4.4)):

The definition of a constexpr function shall satisfy the following requirements:

  • its function-body shall be = delete,= default,or a compound-statement that does not contain

    • a try-block,or

并且“废弃语句”的规则(例如S< int> :: foo中的else语句)都没有覆盖此规则.关于废弃语句的唯一特殊事项是废弃语句没有实例化,废弃语句中的odr-uses不会导致需要使用声明的定义,并且在确定函数的真实返回类型时忽略丢弃的return语句使用占位符返回类型.

我没有看到任何现有的C问题讨论这个,以及文件P0292R1,它提出了constexpr是否不解决与constexpr函数的交互.

相关文章

一.C语言中的static关键字 在C语言中,static可以用来修饰局...
浅谈C/C++中的指针和数组(二) 前面已经讨论了指针...
浅谈C/C++中的指针和数组(一)指针是C/C++...
从两个例子分析C语言的声明 在读《C专家编程》一书的第三章时...
C语言文件操作解析(一)在讨论C语言文件操作之前,先了解一下...
C语言文件操作解析(三) 在前面已经讨论了文件打开操作,下面...