如何在常量求值表达式中获得编译时错误?

huangapple go评论72阅读模式
英文:

How to get a compile time error in constant evaluated expression?

问题

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

  • 如果前提条件在运行时失败,此函数将输出错误消息并终止程序。

  • 如果前提条件在常量表达式内失败,它将导致编译时错误。

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

const int a = (Assert(false),0); // 生成运行时错误
                                 // => 我希望它生成编译时错误

我考虑使用std::is_constant_evaluated

#include <type_traits>

using namespace std;

void runtime_error();

constexpr void 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的内置函数,但没有找到。

有没有什么窍门可以在可能被常量求值的表达式中引发编译时错误?

英文:

I have an Assert function that I use to evaluate assertion:

  • if the precondition fails at runtime, this function will output an error message and it will terminate the program.

  • if the precondition fails inside a constant expression, it will cause a compile time error.

I would like that this function also generates a compile time error when the assertion fails in constant evaluated expression:

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

I thought about using std::is_constant_evaluated: compiler-explorer

#include &lt;type_traits&gt;

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);
    }

I only use GCC, I have look for a builtin function that would cause a compile time error and that would be a constexpr but did not find one.

Is there any trick to get a compile time error in expression that could be constant evaluated?

答案1

得分: 5

你可以调用一个未定义的函数以引发编译时错误。或者,既然你正在使用gcc,你可以在常量部分内调用一个属性错误函数,以在编译此单元时引发编译时错误。要使其工作,你必须启用优化编译。

我看到在gcc 9.2中,使用std::is_constant_expression不起作用,但我成功地使用了__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);
}

我曾经写过一个名为curb的C库,可以执行类似这样的操作。

英文:

You can call a function that is nowhere defined to cause a compile time error. Or, since you are using gcc anyway, you can call a attribute error function from inside the constant part to cause a compile time error during compilation of this unit. To make it work, you have to compile with optimizations enabled.

I see that with std::is_constant_expression it does not work in gcc 9.2, but I managed it to work with __builtin_constant_p.

#include &lt;type_traits&gt;

constexpr void Assert(bool value) {
   if (__builtin_constant_p(value)) {
        if (!value) {
            extern __attribute__(( __error__ ( &quot;error&quot; ) ))
            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);
}

I have once written a library in C I called curb that would do something like this.

huangapple
  • 本文由 发表于 2020年1月6日 18:49:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/59610746.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定