Как получить ошибку времени компиляции в выражении с постоянной оценкой? - PullRequest
1 голос
/ 06 января 2020

У меня есть функция Assert, которую я использую для оценки утверждения:

  • , если предварительное условие не выполняется во время выполнения, эта функция выведет сообщение об ошибке и завершит программу.

  • если предусловие не выполняется внутри константного выражения, это приведет к ошибке времени компиляции.

Мне бы хотелось, чтобы эта функция также генерировала Ошибка времени компиляции, когда утверждение не выполняется в выражении с постоянной оценкой:

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

Я думал об использовании std::is_constant_evaluated: проводник компилятора

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

Я использую только G CC, я искал встроенную функцию, которая вызывала бы ошибку времени компиляции, и это было бы constexpr, но не нашел ее.

Есть ли хитрость для получения ошибки времени компиляции в выражении, которая может быть оценена как константа?

1 Ответ

4 голосов
/ 06 января 2020

Вы можете вызвать функцию, которая нигде не определена, чтобы вызвать ошибку времени компиляции. Или, так как вы все равно используете g cc, вы можете вызвать функцию ошибки атрибута внутри константной части, чтобы вызвать ошибку времени компиляции во время компиляции этого модуля. Чтобы это работало, вы должны скомпилировать с включенной оптимизацией.

Я вижу, что с std::is_constant_expression он не работает в g ​​cc 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);
}

Я однажды написал библиотеку в C я позвонил curb , что бы сделать что-то вроде этого.

...