【发布时间】:2020-11-16 21:54:08
【问题描述】:
C++ 知道 assert(),它允许运行时检查编译为依赖于 NDEBUG 的任何内容。
我想使用编译器代码替换该宏并避免使用预处理器。我需要执行以下操作:
- 如果表达式计算结果为
false,则中断或终止 - 记录调用断言的代码行
- 放弃
NDEBUG构建的检查和传递的表达式
中断/终止应用程序很容易。
在 C++20 中有 std::experimental::source_location,我可以使用它来获取断言的代码位置。
可以使用requires 或constexpr 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
{
}
【问题讨论】:
-
这是为数不多的宏工作之一。您应该使用适合工作的工具。另外,
assert是运行时的东西,if constexpr需要编译时间。 -
@NathanOliver 我相信
if constexpr的条件应该用作启用/禁用断言本身的(编译时)开关。 -
assert或预处理器是否以某种方式冒犯了您?几十年来,它们一直为我们其他人工作得很好。 -
@Silicomancer "commas in expression" 好吧,这只是标准
assert的问题。您可以使用...和__VA_ARGS__编写自己的。 -
没有任何东西可以依赖于
NDEBUG而不依赖于预处理器,因为NDEBUG是一个预处理器宏。
标签: c++ preprocessor assertion c++20