首页 > 解决方案 > 如何在常量评估表达式中获得编译时错误?

问题描述

我有一个Assert用来评估断言的函数:

我希望当断言在常量评估表达式中失败时,这个函数也会生成一个编译时错误:

const int a = (Assert(false),0); //generate a runtime error 
                                 //=> I would like it generates a compile time error

我考虑过使用std::is_constant_evaluatedcompiler-explorer

#include <type_traits>

using namespace std;

void runtime_error();

constexpr void compile_time_error(){} //should generates a compile time error

constexpr void Assert(bool value){
   if (value) return;
   if (is_constant_evaluated())
     compile_time_error();
   else
     runtime_error();
   }

void func(){
    const int a = (Assert(false),0);
    }

我只使用 GCC,我寻找了一个会导致编译时错误的内置函数,这将是一个 constexpr 但没有找到。

是否有任何技巧可以在表达式中获得编译时错误,可以不断评估?

标签: c++gccassertionc++20constant-expression

解决方案


您可以调用未定义的函数以导致编译时错误。或者,由于您无论如何都在使用 gcc,您可以从常量部分内部调用属性错误函数,以在本单元编译期间导致编译时错误。要使其工作,您必须在启用优化的情况下进行编译。

我看到std::is_constant_expression它在 gcc 9.2 中不起作用,但我设法让它与__builtin_constant_p.

#include <type_traits>

constexpr void Assert(bool value) {
   if (__builtin_constant_p(value)) {
        if (!value) {
            extern __attribute__(( __error__ ( "error" ) ))
            void compile_time_error(void);
            compile_time_error();
        }
    } else {
        if (!value) {
            void runtime_error();
            runtime_error();
        }
   }
}

void func(int b) {
    const int a = (Assert(false), 0);
    Assert(b == 0);
}

我曾经在 CI 中编写了一个名为cream的库,它会做这样的事情。


推荐阅读