【问题标题】:Is there any reason not to wrap assert() in a macro that resolves to __builtin_unreachable() in gcc?是否有任何理由不将 assert() 包装在解析为 gcc 中的 __builtin_unreachable() 的宏中?
【发布时间】:2018-02-19 09:38:15
【问题描述】:

上下文:在这个 answer 中,我了解到 gcc 的 __builtin_unreachable() 可能会产生一些令人惊讶的影响性能影响,如下所示:

if(condition) __builtin_unreachable();

被完全剥离,用作优化提示,只要condition可以保证没有任何副作用。

所以我对此的直接反应是我应该创建以下宏,并在我通常使用assert() 的任何地方绝对使用它,因为在assert() 中的副作用诱导代码将是第一个主要错误地点:

// TODO: add handling of other compilers as appropriate.
#if defined(__GNUC__) && defined(NDEBUG)
  #define my_assert(condition) \
    if(!(condition)) __builtin_unreachable()
#else 
  #define my_assert(condition) assert(condition)
#endif

从标准的角度来看,这会在正常构建和 NDEBUG 构建之间造成功能上的分裂,您可以提出一个论点,将该宏排除在 assert() 的标准行为之外。但是,由于无论如何我的代码在断言失败的情况下都会在功能上死气沉沉,所以从行为的角度来看,它是完全等价的。

所以我的问题是:谁能想到不这样做的理由(除了涉及大量间接的断言)?

在你问之前,是的,我已经检查过 gcc 的行为是在 NDEBUG 构建中取消断言。

【问题讨论】:

  • 据我所知,没有理由不这样做。您假设在发布版本中进行优化,并在调试版本中用断言替换它以捕获编程错误。
  • “在任何地方都使用它”的方法不会真正起作用,因为调试断言通常包含仅在调试模式下可用的变量和调用。更好的想法是定义一个具有更合适名称的专用宏,例如my_assume,并仅在适当的地方使用它。
  • 一般情况下,可以把东西放在有副作用的断言中,所以我不会这样做。例如,可能有一个昂贵的函数来检查一些不变量:assert(isStructureValid());。我绝对不想看到在发布版本中调用该函数。因此,正如其他人建议的那样,为此功能创建一个新的 assume (或其他名称)宏。或者,使用编译器魔法,如果condition 可以在编译时进行评估,则仅在发布版本中应用签入。
  • @geza 将此限制为编译时条件会破坏整个目的(请参阅链接的问题以获取示例)。

标签: c++ gcc optimization assert


【解决方案1】:

是的,有理由不使用它。 有些人使用以下结合了断言和异常(assert(x>0); if (!(x<0)) throw std::logic_error(".."))的防御性代码实践 - 请参阅此答案:

Test Cases AND assertion statements

您的宏默默地破坏了发布版本的异常部分。

【讨论】:

  • 我真的不喜欢这种做法,因为它将编程错误和运行时错误混为一谈。在我看来,这种说法没有任何意义。我的代码库不会因此受到影响,但请记住这是一件好事。
  • 我看不到那个 tbh 的价值。它似乎违背了assert() 对发布代码的运行时影响为零的目的。如果这是你想要的,也可以只使用例外。
  • 这不是防御性的而是冗余代码。如果您需要在发布版本中进行检查,那么要么创建一个特殊的、即使在发布模式下编译的 release_assert,也可以只使用异常抛出。断言+抛出是不好的做法。
  • @Galik 这不是成语是否有价值,而是使用我的宏会导致在看似定义明确的程序中出现 UB,这是一个完全有效的观点,并且强调了对宏进行适当命名的必要性。
  • @Frank:我不同意。如果一个程序不满足断言,那么它就不是一个定义良好的程序。即使该断言不存在,因为它已被编译掉。但我同意你的观点,应该为此目的使用不同的命名宏。
猜你喜欢
  • 2020-11-28
  • 1970-01-01
  • 2011-01-09
  • 2023-03-30
  • 2020-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
相关资源
最近更新 更多