5

I am trying to define the following 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

But i get the following error on Linux -

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

and it points to the first ')' in the statment

How can i define a macro that contains a #?

Solution Update:

As stated in this thread Pragma in define macro the syntax that worked is:

#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
darkThoughts
  • 403
  • 6
  • 18

1 Answers1

7

How can i define a macro that contains a #?

You can't (define a macro that contains a directive, that is. # can still be used in macros for stringization and as ## for token concatenation). That's why _Pragma was invented and standardized in C99. As for C++, it's definitely in the C++11 standard and presumably the later ones.

You can use it as follows:

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

With that,

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

preprocesses to

# 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"

As you can see, the _Pragmas are expanding to #pragma directives. Since _Pragma is standard, you should be able to avoid the #ifdef here if Microsoft supports it.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • VS throws the error "this declaration has no storage class or type specifier" when using the proposed syntax. I have found a solution and will update my post accordingly – darkThoughts Jul 16 '17 at 16:51
  • @darkThoughts With your solution, the `n` argument will be just the letter `n`. Its value won't get interpolated into the `pragma`. – Petr Skocik Jul 16 '17 at 16:56
  • So at least in Linux where it's supported i should use your solution? – darkThoughts Jul 16 '17 at 17:00
  • @darkThoughts My solution should work on every standard-compliant compiler. It definitely does work on gcc/linux and clang/linux. – Petr Skocik Jul 16 '17 at 17:03