как мне утверждать из функции constexpr с отключенными исключениями?

Если я хочу подтвердить обнаруженную ошибку из функции constexpr C ++ 11 во встроенной конструкции небольшого процессора, отключение прерываний отменяет предлагаемый метод обработки ошибок (см. Ответ Эрика Ниблерса здесь)

Вот пример сокращенного кода:

constexpr bool isANumber(char c)
{
    return (c >= '0' && c <= '9');
}

constexpr int charToInt(char c)
{
    return (!isANumber(c))? throw std::logic_error("not a number"):
        c - '0';
}

Насколько мне известно:

  • static_assert не допускается, потому что входные данные могут быть значениями времени выполнения
  • assert может заставить функцию оцениваться во время выполнения, а обработчик assert втягивает столько всего, что переполняет флеш-память большинства чипов Cortex
  • бросить не получится, потому что я отключил исключения

Какая работа?

Примечание. При использовании C ++ во встроенных средах с ограниченными ресурсами необходимо отключать исключения, поскольку они используют избыточную оперативную память (например, мой чип имеет только 16 КБ ОЗУ). Это обычная практика.


person odinthenerd    schedule 03.02.2016    source источник
comment
В C ++ 14 вам разрешено assert в constexpr функциях.   -  person 101010    schedule 03.02.2016
comment
@ 101010 спасибо за комментарий, он мне нужен на С ++ 11, но добавил это к моему вопросу   -  person odinthenerd    schedule 03.02.2016
comment
@columbo спасибо за ссылку, похоже, мой вопрос может быть дубликатом   -  person odinthenerd    schedule 03.02.2016
comment
похоже, что assert также не подходит, потому что GCC assert перетаскивает в двоичный файл так много всего, что я не поместился бы на большинстве чипов ARM Cortex   -  person odinthenerd    schedule 03.02.2016
comment
Как на вашей платформе использовать эквивалент assert в функции, отличной от constexpr? Не так трудно преобразовать почти любой обработчик времени выполнения в constexpr-условно безопасный, но без решения для не-constexpr я не уверен, чего вы ожидаете.   -  person Yakk - Adam Nevraumont    schedule 03.02.2016
comment
Эквивалент assert вызывает аппаратный обработчик сбоев, функциональность которого настраивается, но обычно запускает точку останова или сбрасывает систему. Вот почему я бы предпочел выдвинуть ошибку на время компиляции.   -  person odinthenerd    schedule 04.02.2016


Ответы (1)


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

int assert_failed() {
    static int i = 5;
    return i++;
}
constexpr int cheap_assert(bool i) {
    return i == 1 ? 0 : assert_failed();
}

constexpr unsigned operator""_my_literal(const char* s, std::size_t size) {
    return cheap_assert(size < 10), 0;
}
person odinthenerd    schedule 03.02.2016
comment
@Orient не на MSVC2015, но я думаю, что вы правы и, вероятно, это ошибка Microsoft - person odinthenerd; 04.02.2016