2014-01-07 4 views
11

В C++ 14 мы получаем upgraded version of constexpr, что означает, что теперь можно будет использовать циклы, if-statement и switch. Рекурсия уже возможна, как в C++ 11.Как эффективно отлаживать функции constexpr?

Я понимаю, что constexpr функции/код должны быть довольно простыми, но все же возникает вопрос: как эффективно отладить его?

Даже в «Язык программирования C++, 4-е издание« есть предложение, которое может быть затруднено для debuggig.

+0

Так же, как вы отлаживаете шаблоны метапрограмм :-) –

+2

Также обратите внимание, что 'constexpr' функции не имеют * *, которые должны быть оценены статически. Если вы предоставляете аргумент non-constexpr, у вас есть обычный вызов функции, который вы должны уметь отлаживать. –

+1

Я не понимаю, в чем проблема ... – Mehrdad

ответ

8

Есть два важных аспекта для отладки constexpr функций.

1) Убедитесь в том, что вычислить правильный результат

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

2) Убедитесь в том, что они могут быть оценены во время компиляции

Это может быть проверена путем оценки функции в качестве правой стороны constexpr присваивания значения переменной.

constexpr auto my_var = my_fun(my_arg); 

Для того, чтобы это работало, my_fun может а) только во время компиляции константного выражения в качестве фактических аргументов. То есть my_arg является литералом (встроенным или определяемым пользователем) или ранее вычисленной переменной constexpr или параметром шаблона и т. Д., И b) он может вызывать только функции constexpr в своей реализации (поэтому нет виртуальных, не лямбда-выражений и т. Д.).

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

К счастью, поскольку вы можете отделить время выполнения и время компиляции constexpr, отладка их не так сложна, как отладка шаблонов метапрограмм (которые могут выполняться только во время компиляции).

+2

Отлично! поэтому в основном вы можете использовать «нормальную» отладку во время выполнения, а затем только убедитесь, что она правильно вычисляется во время компиляции. Надеюсь, что constexpr значительно упростит метапрограммирование. Я думаю, что это отличная функция C++ 1y – fen

+1

@fen да, именно так я это делаю. И это намного проще, чем шаблон-метапрограммирование. Например, 'constexpr'' switch'-statement эквивалентен нескольким специализациям шаблонов классов в TMP. Это значительно сокращает количество строк кода, которые нужно поддерживать, и у вас всегда есть возможность запускать тот же код с параметрами времени выполнения. – TemplateRex

+0

Я нашел замечательную статью здесь: http://cpptruths.blogspot.com/2011/07/want-speed-use-constexpr-meta.html описывает, как constexpr упрощает жизнь. – fen

0

Если при отладке вы имеете в виду «сделать это известно, что определенное выражение не желаемое значение», вы можете проверить его во время выполнения

#include <stdexcept> 
#include <iostream> 

constexpr int test(int x){ return x> 0 ? x : (throw std::domain_error("wtf")); } 

int main() 
{ 
    test(42); 
    std::cout<< "42\n"; 
    test(-1); 
    std::cout<< "-1\n"; 
} 
0

Вот мое предложение.

Создать макрос:

#ifdef NDEBUG 
#define OPTIONAL_CONSTEXPR constexpr 
#else 
#define OPTIONAL_CONSTEXPR 
#endif 

и заменить код, как

constexpr INT х;

с

OPTIONAL_CONSTEXPR int x; 

Тогда, если вы отладки, вы будете иметь возможность шагнуть в код. Но когда вы компилируете в режиме освобождения, вы получите полную выгоду от constexpr.

+2

За исключением что это сломает любой код, основанный на квалификации constexpr, такой как размеры массива и аргументы шаблона. – rubenvb

+0

Да, это действительно не работает, пожалуйста, удалите этот ответ. – einpoklum

+0

Право - моя ошибка –

0

Ответ, который я написал 3 апреля '15, явно ошибочен. Я не понимаю, о чем я думал.

Вот «реальный» ответ - метод, который я использую сейчас.

a) Напишите свою функцию constexpr, как обычно. Пока это не работает.

b) когда функция вызывается во время компиляции - компиляция завершается с не более чем сообщением о влиянии функции "invalid constexpr". Это затрудняет понимание сути проблемы.

c) Сделайте небольшую программу тестирования, которая вызывает функцию с параметрами, известными только во время выполнения. Запустите тестовую программу с помощью отладчика. Вы обнаружите, что вы можете проследить эту функцию обычным образом.

Мне потребовалось довольно долгое время, чтобы понять это.

Смежные вопросы