如何有效地调试constexpr函数

How to effectively debug constexpr functions?

本文关键字:constexpr 函数 调试 有效地      更新时间:2023-10-16

在C++14中,我们获得了constexpr的升级版本,这意味着现在可以使用循环、if语句和开关。在C++11中,递归已经成为可能。

我知道constexpr函数/代码应该很简单,但问题仍然存在:如何有效地调试它

即使在"C++编程语言,第4版"中,也有一句话认为调试可能很困难。

调试constexpr函数有两个重要方面。

1)确保他们计算出正确的结果

在这里,您可以使用常规的单元测试、断言或运行时调试器来逐步执行代码。与测试常规函数相比,这里没有什么新鲜事。

2)确保它们可以在编译时进行评估

这可以通过将函数评估为constexpr变量赋值的右侧来进行测试。

constexpr auto my_var = my_fun(my_arg);

为了实现这一点,my_fun可以a)仅将编译时常数表达式作为实际参数。例如,my_arg是一个文本(内置或用户定义)或以前计算的constexpr变量或模板参数等,b)它在实现中只能调用constexpr函数(因此没有虚拟值,没有lambda表达式等)

注意:在constexpr函数的编译时评估过程中,很难实际调试编译器的代码生成实现。您必须在编译器上附加一个调试器,才能真正解释代码路径。也许将来Clang的某个版本会让你这样做,但这在目前的技术下是不可行的。

幸运的是,因为您可以将constexpr函数的运行时和编译时行为解耦,所以调试它们并不像调试模板元程序(只能在编译时运行)那么难。

我在2015年4月3日写的答案显然是错误的。我不明白自己在想什么。

这是"真正的"答案——我现在使用的方法。

a) 像往常一样编写constexpr函数。到目前为止,它不起作用。

b) 当函数在编译时被调用时,编译失败,只会显示一条大意为"invalidconstexpr"函数的消息。这使得我们很难知道问题到底是什么

c) 制作一个小测试程序,该程序只在运行时调用参数已知的函数。使用调试器运行测试程序。您会发现,您可以以正常的方式跟踪函数。

我花了很长时间才弄明白这一点。

如果你正在使用gcc,你可以尝试这个

有一个关于它的介绍

如果调试的意思是"让它知道某个表达式不是所需的值",您可以在运行时检查它

#include <stdexcept>
#include <iostream>
constexpr int test(int x){ return x> 0 ? x : (throw std::domain_error("wtf")); }
int main()
{
test(42);
std::cout<< "42n";
test(-1);
std::cout<< "-1n";
}