如何有效地调试constexpr函数
How to effectively debug constexpr functions?
在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
函数的运行时和编译时行为解耦,所以调试它们并不像调试模板元程序(只能在编译时运行)那么难。
这是"真正的"答案——我现在使用的方法。
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";
}
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- constexpr 函数获取常量字符*
- 如何在 constexpr 函数中实现回退运行时
- 在非 constexpr 函数中作为左值传递的变量上使用 'constexpr' 函数
- NVCC 错误:string_view.h:constexpr 函数返回是非常量
- constexpr函数中的静态constexpr变量
- 在 constexpr 函数中断言
- G++ 编译器是否在未使用返回值的情况下将 constexpr 函数视为常规函数?
- constexpr 函数的常量引用参数:gcc/msvc vs clang/icc
- constexpr 函数在编译时获取值,即使我的变量不是 constexpr
- 如何正确地对 constexpr 函数进行单元测试
- 为什么 std::launder 是一个 constexpr 函数?
- 我可以使用 constexpr 函数声明一个静态数组吗?
- 用于连接向量的 Constexpr 函数
- 在非constexpr函数上添加的constexpr限定符不会触发任何警告
- 为什么 std::get<T> 其中 T 是调用 constexpr 函数失败的结果?
- 在constexpr函数中插入许多模板
- 在enable_if_t中调用 constexpr 函数
- constexpr 函数中的 for 循环无法使用 MSVC 19.23 进行编译