我可以为assert()

时间:2019-09-16 05:27:14

标签: c++ gcc assert noreturn

Glibc在noreturn中使用GCC的assert.h属性:

extern void __assert_fail (...)
 ... __attribute__ ((__noreturn__));

这会导致GCC在进入调试器之前优化掉所有局部变量和this指针。即使在-Og级别和-O0级别也进行了优化级别,因此忽略了许多其他有用的优化,以至于测试变得非常缓慢。

理想情况下,我只想从此处删除__noreturn__属性。我不在乎我的assert()的工作速度是否快一点,我想看看它触发的位置和原因。

我是否可以使用GCC命令行标志或任何其他机制来禁用__noreturn__优化,而不禁用其他优化?


可运行的示例代码:

#include <cassert>
int test(int x)
{
    assert(x != 1);
    return x + 10;
}
int main(int argc, char *argv[])
{
    return test(argc);
}

此示例在不带参数的情况下运行时断言。当使用带有g++ -Og -g -ggdb -otest test.cc的GCC 7.4进行编译并在gdb中运行时,可以看到回溯是无用的:

#4  0x0000555555554676 in test (x=<optimized out>) at test.cc:4
#5  0x000055555555467f in main (argc=<optimized out>, argv=<optimized out>) at test.cc:9

1 个答案:

答案 0 :(得分:0)

Jarod42关于使用自定义宏覆盖assert的评论给出了一个主意:

g++ -D__noreturn__=    ...usual options follow...

这仅通过将属性定义更改为空括号而起作用。 它不漂亮,但至少可以正常工作。

如果有一个关于在noreturn调用之前或类似的操作之前丢弃局部变量的特定优化标记,那会很好,但是我一直找不到。所以到目前为止,这是我最好的。