避免 C++20 中互斥函数调用的预处理器

Avoiding preprocessor for mutual exclusive function call in C++20

请考虑以下小功能。它为以编程方式破坏调试器提供了编译器抽象:

inline constexpr void BreakDebug()
{
   #ifdef __GNUC__
      __builtin_trap();
   #elif defined _MSC_VER
      __debugbreak();
   #endif
}

我想重写函数并使用 C++20 代码替换预处理器指令。由于 __builtin_trap__debugbreak 是特定于编译器且互斥的,我不能使用简单的 if constexpr 因为我会得到编译错误。

假设我将使用 constexpr 枚举常量包装编译器宏 __GNUC___MSC_VER...那该怎么做?

你只需要一个不被调用的函数的声明(不需要定义,因为它不会被调用):

inline constexpr void BreakDebug()
{
   #ifdef __GNUC__
   constexpr bool GNU = true; 
   constexpr void __debugbreak();
   #elif defined _MSC_VER
   constexpr bool GNU = false;  
   constexpr void __builtin_trap();
   #endif


   if constexpr (GNU){
      __builtin_trap();
   } else {
      __debugbreak();
   }
}

通过仅声明不存在且永远不会调用的函数,您可以避免在签名不正确的情况下出现链接器错误。

显然,那些内置函数也可以变成依赖名称。我检查了这个 here。因此,使潜在的格式错误的代码依赖起作用的常用技巧:

enum compiler_t{
    gnu,
    msvc
    };

inline constexpr compiler_t compiler = 
#ifdef __GNUC__
  compiler_t:: gnu;
#else
  compiler_t:: msvc;
#endif

template <class...Args>
inline constexpr void BreakDebug(Args...args)
{

   if constexpr (compiler == gnu){
      __builtin_trap(args...);
   } else {
      __debugbreak(args...);
   }
}

int main(){
   BreakDebug();
   return 0;
}