提问者:小点点

在C++20中实现无预处理的assert


C++知道assert(),它允许运行时检查,根据ndebug编译为空。

我想用编译器代码替换那个宏,避免使用预处理器。 我需要执行以下操作:

  • 如果表达式的计算结果为false
  • ,则中断或终止
  • 记录调用断言的代码行
  • 放弃ndebug生成
  • 的检查和传递的表达式

中断/终止应用程序很容易。

在C++20中有std::experimental::source_location,我可以使用它来获取断言的代码位置。

编译时条件可以使用requiresconstexpr if完成

然而,我不知道如何才能避免对表达式的评估。 当将MyAssert(expression)实现为函数时,我需要将表达式结果作为函数参数传递,这意味着它无论如何都要计算,即使函数内部没有使用该参数。

在C++20中有没有解决这个问题的方法?

编辑:模板示例:

template <typename T> requires (gDebug)
void assertTrue(const T& pResult, const std::experimental::source_location& pLocation) noexcept
{
   if (!static_cast<bool>(pResult))
   {
      // error handling
   }
}

template <typename T> requires (!gDebug)
void assertTrue(const T&) noexcept
{
}

共1个答案

匿名用户

不确定我是否正确理解了这个问题。

然而,我不知道如何才能避免对表达式的评估。

我想您说的是禁用调试而希望函数为NOOP的情况。 我看到两个选项:

您可以使用宏。 宏可能被误用,但它们有自己的位置,“传递表达式”而不求值是宏的一种情况。

或者,传递一个callable,该callable返回您想要断言的结果。 仅当gdebug==true时调用它:

template <typename F> requires (gDebug)
void assertTrue(const F& f, const std::experimental::source_location& pLocation) noexcept
{
   if (!static_cast<bool>(f()))
   {
      // error handling
   }
}

但这会使调用变得相当冗长。 例如,一个总是失败的:

assertTrue( [](){ return false; });

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++20|中|预处理|assert)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?