C++ 包含#pragma的宏定义

C++ 包含#pragma的宏定义,c++,macros,C++,Macros,我正在尝试定义以下宏: #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() #pra

我正在尝试定义以下宏:

#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))
它指向陈述中的第一个“)”

如何定义包含#的宏

解决方案更新:

如本线程所述,有效的语法是:

#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
如何定义包含#的宏

您不能(定义包含指令的宏,即。#仍然可以在宏中用于字符串化,而作为##用于标记连接)。这就是为什么
\u 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"
如您所见,
\u Pragma
s正在扩展为
\Pragma
指令。
既然
\u Pragma
是标准的,如果Microsoft支持,您应该可以避免这里的
\ifdef

VS可以处理
\Pragma
语法很好,为什么要使用
\u Pragma
呢?只要在任何地方使用
#pragma
。@VTT不在定义内@aschepler如果在这两种情况下
#pragma
语法都有效,那么定义这个宏就没有意义了。@VTT之所以在这里定义,是因为反复编写_pragma(pack(push,n))或u pragma(pack(pop))很痛苦。它是用来做捷径的purposes@darkThoughts这些宏只短了6个符号,考虑到您需要#在定义这些宏的地方包含头,因此似乎节省不了那么多(如果有的话)。VS在使用建议的语法时抛出错误“此声明没有存储类或类型说明符”。我已经找到了解决方案,将更新我的帖子accordingly@darkThoughts在您的解决方案中,
n
参数将只是字母
n
。它的值不会被插入到
pragma
中。因此,至少在支持它的Linux中,我应该使用您的解决方案?@darkthoughs我的解决方案应该适用于所有符合标准的编译器。它在gcc/linux和clang/linux上确实有效。