C++ 我可以禁用GCC';assert()的s noreturn属性
Glibc在C++ 我可以禁用GCC';assert()的s noreturn属性,c++,gcc,assert,noreturn,C++,Gcc,Assert,Noreturn,Glibc在assert.h中使用GCC的noreturn属性: extern void __assert_fail (...) ... __attribute__ ((__noreturn__)); 这会导致GCC在进入调试器之前优化掉所有局部变量和这个指针。即使在-Og级别和-O0级别,优化也会发生,因此忽略了许多其他有用的优化,以至于测试变得非常缓慢 理想情况下,我只想从那里删除\uuu noreturn\uu属性。我不在乎我的assert()是否工作得快一点,我想看看它在哪里启动,为
assert.h
中使用GCC的noreturn
属性:
extern void __assert_fail (...)
... __attribute__ ((__noreturn__));
这会导致GCC在进入调试器之前优化掉所有局部变量和这个指针。
即使在-Og
级别和-O0
级别,优化也会发生,因此忽略了许多其他有用的优化,以至于测试变得非常缓慢
理想情况下,我只想从那里删除\uuu noreturn\uu
属性。我不在乎我的assert()
是否工作得快一点,我想看看它在哪里启动,为什么启动
是否有一个GCC命令行标志或任何其他机制可以用来禁用\uuu noreturn\uuu
优化,而不禁用其他优化
可运行示例代码:
#include <cassert>
int test(int x)
{
assert(x != 1);
return x + 10;
}
int main(int argc, char *argv[])
{
return test(argc);
}
Jarod42关于使用自定义宏覆盖
assert
的评论给出了一个想法:
g++ -D__noreturn__= ...usual options follow...
这只需将属性定义更改为空括号即可。
这并不漂亮,但至少能起作用
如果在noreturn调用之前有一个特定的关于丢弃局部变量的优化标志,或者类似的标志,那就太好了,但是我还没有找到一个。这是目前为止我所能做的最好的了。你确定它是assert而不是-Og吗?您是否已经创建了自己的断言函数并将其放在适当的位置?@JVApen手动编辑
/usr/include/assert.h
以注释掉属性似乎可以阻止它优化局部变量。但这似乎是一个相当残酷的解决方案,并且会扰乱系统升级。您仍然可以“覆盖”自己的assert
宏。@Jarod42:这是一项工作,因为您只想更改\u assert\u fail
路径。不过,一些不可移植的宏滥用可能会解决这个问题。我想你应该在\u assert\u fail
中添加一个额外的参数(!),例如int()
,然后添加你自己的重载,它仍然调用原始的。禁用该属性可能会让优化器保留足够的x
,以便在这种情况下在GDB中看到它,但这并不是一个根本性的改变:毕竟,x
在该函数中使用。
g++ -D__noreturn__= ...usual options follow...