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

问题描述 投票:2回答:1

请考虑以下小功能。它提供了编译器的抽象,可以在程序上突破调试器。

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

我想重写这个函数,用C++20的代码来代替前处理程序的指令。由于 __builtin_trap__debugbreak 是编译器特有的,是相互排斥的,我不能用简单的 if constexpr 因为我会得到一个编译错误。

假设我将编译器宏包装成 __GNUC___MSC_VER 使用 constexpr 枚举常数......怎么能这样做呢?

c++ c-preprocessor constexpr c++20
1个回答
4
投票

显然,这些内置函数也可以变成依赖名。我检查了这个 此处. 因此,通常的技巧,包括使潜在的错误的代码依赖于工作。

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;
}

4
投票

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

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();
   }
}

通过只声明那个不存在的、你永远不会调用的函数,你可以在签名不正确的情况下避免链接器错误。

© www.soinside.com 2019 - 2024. All rights reserved.