【问题标题】:macro definition containing #pragma包含#pragma 的宏定义
【发布时间】:2017-12-21 04:34:21
【问题描述】:

我正在尝试定义以下宏:

#if defined(_MSC_VER)
    #define PRAGMA_PACK_PUSH(n)  __pragma(pack(push, n))
    #define PRAGMA_PACK_POP()    __pragma(pack(pop))
#else
    #define PRAGMA_PACK_PUSH(n)     #pragma (pack(push, n))
    #define PRAGMA_PACK_POP()       #pragma (pack(pop))
#endif

但我在 Linux 上收到以下错误 -

 error: '#' is not followed by a macro parameter
  #define PRAGMA_PACK_PUSH(n)  #pragma (pack(push, n))

它指向语句中的第一个')'

如何定义包含# 的宏?

解决方案更新:

正如该线程Pragma in define macro 中所述,有效的语法是:

#if defined(_MSC_VER)
    #define PRAGMA_PACK_PUSH(n)  __pragma(pack(push, n))
    #define PRAGMA_PACK_POP()    __pragma(pack(pop))
#else
    #define PRAGMA_PACK_PUSH(n)     _Pragma("pack(push, n)")
    #define PRAGMA_PACK_POP()       _Pragma("pack(pop)")
#endif

【问题讨论】:

  • VS可以处理#pragma的语法就好了,你为什么要用__pragma呢?随处使用#pragma
  • @VTT 不在定义内!
  • @VTT 定义在这里,因为一遍又一遍地编写 _pragma(pack(push, n)) 或 __pragma(pack(pop)) 很痛苦。它用于快捷方式
  • @darkThoughts 这些宏只短了 6 个符号,考虑到您需要在定义这些宏的位置添加 #include 标头,它似乎并没有节省太多(如果有的话)。

标签: c++ macros


【解决方案1】:

如何定义包含 # 的宏?

你不能(定义一个包含指令的宏,也就是说。# 仍然可以在宏中用于字符串化,并作为 ## 用于标记连接)。这就是为什么_Pragma 在 C99 中被发明和标准化的原因。至于C++,肯定是C++11的标准,估计是后来的。

您可以按如下方式使用它:

#define PRAGMA(X) _Pragma(#X)
#define PRAGMA_PACK_PUSH(n)     PRAGMA(pack(push,n))
#define PRAGMA_PACK_POP()       PRAGMA(pack(pop))

这样,

PRAGMA_PACK_PUSH(1)
struct x{
    int i;
    double d;
};
PRAGMA_PACK_POP()

预处理到

# 10 "pack.c"
#pragma pack(push,1)
# 10 "pack.c"

struct x{
 int i;
 double d;
};

# 15 "pack.c"
#pragma pack(pop)
# 15 "pack.c"

如您所见,_Pragmas 正在扩展为 #pragma 指令。 由于_Pragma 是标准的,如果微软支持,你应该可以避免这里的#ifdef

【讨论】:

  • VS 在使用建议的语法时抛出错误“此声明没有存储类或类型说明符”。我找到了解决方案,并将相应地更新我的帖子
  • @darkThoughts 使用您的解决方案,n 参数将只是字母 n。它的值不会被插入到pragma
  • 所以至少在支持它的 Linux 中我应该使用你的解决方案?
  • @darkThoughts 我的解决方案应该适用于所有符合标准的编译器。它确实适用于 gcc/linux 和 clang/linux。
猜你喜欢
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多