我收到了很多关于开关的警告,这些开关只覆盖了枚举的一部分。因此,我希望为所有这些开关设置一个“默认值”,并在这种情况下放置__builtin_unreachable(GCC内置),这样编译器就知道这种情况是不可达的。然而,我知道GCC4.3还不支持这个内置功能。有什么好的方法来模拟这个功能吗?我考虑过取消引用一个空指针,但是这可能会有其他不希望的效果/警告等等。你有什么更好的主意吗?
__builtin_unreachable
hgb9j2n61#
你可以调用一个声明为_Noreturn的内联函数,将调用后的任何代码标记为不可访问。编译器可以抛出这样一个函数后的任何代码。如果函数本身是static(并且返回),编译器通常也会内联该函数。下面是一个例子:
_Noreturn
static
static _Noreturn void unreachable() { return; /* intentional */ } /* ... */ foo(); bar(); /* should better not return */ unreachable(); baz(); /* compiler will know this is not reachable */
请注意,如果标记为_Noreturn的函数确实返回,则会调用未定义的行为。请确保永远不会调用上述函数。
hmae6n7t2#
嗯,类似于(自从Python 4.5中出现__builtin_unreachable()以来):
#define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #if GCC_VERSION >= 40500 #define my_unreachable() __builtin_unreachable() #else #define my_unreachable() do { printf("Oh noes!!!111\n"); abort(); } while(0) #endif
xzabzqsa3#
abort(保留内核转储)或throw(允许备用数据捕获)是否能满足您的需求?你真的想让switch语句不覆盖整个枚举吗?我几乎总是尝试列出所有可能的情况(到no-op),没有默认情况,这样gcc会在添加新枚举时警告我,因为它可能需要处理它们,而不是让它安静地(在编译期间)落入默认值。
abort
throw
0ejtzxu14#
保持简单:
assert(false);
或者,更好的是:
#define UNREACHABLE (!"Unreachable code executed!") assert(UNREACHABLE);
55ooxyrt5#
template<unsigned int LINE> class Unreachable_At_Line {}; #define __builtin_unreachable() throw Unreachable_At_Line<__LINE__>()
因为你想让编译器忽略无法达到的代码,下面是最简单的方法。
#define __builtin_unreachable() { struct X {X& operator=(const X&); } x; x=x; }
编译器优化掉x = x;指令,尤其是当它不可访问时。用法如下:
x = x;
int foo (int i) { switch(i) { case 0: return 0; case 1: return 1; default: return -1; } __builtin_unreachable(); // never executed; so compiler optimizes away }
如果你把__builtin_unreachable()放在foo()的开头,那么编译器会为未实现的operator =生成链接器错误。我在gcc 3.4.6(64位)中运行了这些测试。
__builtin_unreachable()
foo()
operator =
57hvy0tb6#
即将发布的C标准(C23,ISO/IEC 9899:2023)的2023修订版将包含新宏unreachable
unreachable
#include <stddef.h> void unreachable(void);
具有GCC的__builtin_unreachable的影响。
6条答案
按热度按时间hgb9j2n61#
你可以调用一个声明为
_Noreturn
的内联函数,将调用后的任何代码标记为不可访问。编译器可以抛出这样一个函数后的任何代码。如果函数本身是static
(并且返回),编译器通常也会内联该函数。下面是一个例子:请注意,如果标记为
_Noreturn
的函数确实返回,则会调用未定义的行为。请确保永远不会调用上述函数。hmae6n7t2#
嗯,类似于(自从Python 4.5中出现__builtin_unreachable()以来):
xzabzqsa3#
abort
(保留内核转储)或throw
(允许备用数据捕获)是否能满足您的需求?你真的想让switch语句不覆盖整个枚举吗?我几乎总是尝试列出所有可能的情况(到no-op),没有默认情况,这样gcc会在添加新枚举时警告我,因为它可能需要处理它们,而不是让它安静地(在编译期间)落入默认值。
0ejtzxu14#
保持简单:
或者,更好的是:
55ooxyrt5#
编辑:
因为你想让编译器忽略无法达到的代码,下面是最简单的方法。
编译器优化掉
x = x;
指令,尤其是当它不可访问时。用法如下:如果你把
__builtin_unreachable()
放在foo()
的开头,那么编译器会为未实现的operator =
生成链接器错误。我在gcc 3.4.6(64位)中运行了这些测试。57hvy0tb6#
即将发布的C标准(C23,ISO/IEC 9899:2023)的2023修订版将包含新宏
unreachable
具有GCC的
__builtin_unreachable
的影响。