简体   繁体   English

模拟 GCC 的 __builtin_unreachable?

[英]Emulating GCC's __builtin_unreachable?

I get a whole lot of warnings about switches that only partially covers the range of an enumeration switched over.我收到了很多关于开关的警告,这些开关只部分覆盖了枚举切换的范围。 Therefor, I would like to have a "default" for all those switches and put __builtin_unreachable (GCC builtin) in that case, so that the compiler know that case is not reachable.因此,我想为所有这些开关设置一个“默认值”,并在这种情况下放置__builtin_unreachable (GCC 内置),以便编译器知道这种情况无法访问。

However, I came to know that GCC4.3 does not support that builtin yet.但是,我了解到 GCC4.3 还不支持该内置函数。 Is there any good way to emulate that functionality?有什么好的方法可以模拟该功能吗? I thought about dereferencing a null pointer instead, but that may have other undesirable effects/warnings and such.我考虑过取消引用 null 指针,但这可能会产生其他不良影响/警告等。 Do you have any better idea?你有更好的主意吗?

You can call an inline function declared _Noreturn to mark anything after that call as unreachable. 您可以调用声明为_Noreturn的内联函数,将该调用后的任何内容标记为无法访问。 The compiler is allowed to throw out any code after such a function. 允许编译器在这样的函数之后抛出任何代码。 If the function itself is static (and does return), the compiler will usually also inline the function. 如果函数本身是static (并且确实返回),编译器通常也会内联函数。 Here is an example: 这是一个例子:

static _Noreturn void unreachable() {
    return; /* intentional */
}

/* ... */

foo();
bar(); /* should better not return */
unreachable();
baz(); /* compiler will know this is not reachable */

Notice that you invoke undefined behavior if a function marked _Noreturn indeed returns. 请注意,如果标记为_Noreturn的函数确实返回,则调用未定义的行为。 Be sure that said function will never be called. 确保永远不会调用所述函数。

Hmm, something like (since __builtin_unreachable() appeared in 4.5): 嗯,像(因为__builtin_unreachable()出现在4.5):


#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

Would abort (leaving a core dump) or throw (allowing for alternate data capture) accommodate your needs? abort (离开核心转储)或throw (允许备用数据捕获)可以满足您的需求吗?

Do you really want to have switch statements that don't cover the full enumeration? 你真的想拥有不包括完整枚举的switch语句吗? I nearly always try to list all the possible cases (to no-op) with no default case so that gcc will warn me if new enumerations are added, as it may be required to handle them rather than letting it silently (during compile) fall into the default. 我几乎总是尝试列出所有可能的情况(没有操作)没有默认情况,这样gcc会警告我是否添加了新的枚举,因为它可能需要处理它们而不是让它静默(在编译期间)掉落进入默认值。

template<unsigned int LINE> class Unreachable_At_Line {}; 
#define __builtin_unreachable() throw Unreachable_At_Line<__LINE__>()

Edit : 编辑

Since you want to have unreachable code to be omitted by compiler, below is the simplest way. 由于您希望编译器省略无法访问的代码,因此以下是最简单的方法。

#define __builtin_unreachable() { struct X {X& operator=(const X&); } x; x=x; }

Compiler optimizes away x = x; 编译器优化了x = x; instruction especially when it's unreachable. 指令,特别是当它无法到达时。 Here is the usage: 这是用法:

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
}

If you put __builtin_unreachable() in the beginning of foo() then compiler generates a linker error for unimplemented operator = . 如果将__builtin_unreachable()放在foo()的开头,则编译器会为未实现的operator =生成链接器错误 I ran these tests in gcc 3.4.6 (64-bit). 我在gcc 3.4.6(64位)中运行了这些测试。

keep it simple: 把事情简单化:

assert(false);

or, better yet: 或者,更好的是:

#define UNREACHABLE (!"Unreachable code executed!")

assert(UNREACHABLE);

The upcoming 2023 revision of the C standard (C23, ISO/IEC 9899:2023) is going to have a new macro unreachable即将在 2023 年修订的 C 标准(C23,ISO/IEC 9899:2023)将有一个新的宏unreachable

#include <stddef.h>
void unreachable(void);

with the effect of gcc's __builtin_unreachable .具有 gcc 的__builtin_unreachable的效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM