https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126665

            Bug ID: 126665
           Summary: C/C++: Emit warnings when #pragma pack meets a string
                    constant that is a macro
           Product: gcc
           Version: 16.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dragon-archer at outlook dot com
  Target Milestone: ---

>From https://gcc.gnu.org/onlinedocs/gcc/Structure-Layout-Pragmas.html, there're
only 2 allowed syntax of #pragma pack(push):
1. #pragma pack(push, n), which pushes current packing to stack and set new
packing to n
2. #pragma pack(push), which pushes current packing to stack and set to default
packing (same as #pragma pack(push, 0))

However, the actually supported syntax by GCC is #pragma pack(push[, id][,
<n>]), which can be tested with `#pragma pack(push, +-*)`
```
test.cpp:17:20: warning: malformed '#pragma pack(push[, id][, <n>])' - ignored
[-Wpragmas]
   17 | #pragma pack(push, +-*)
      |         
```
This may comes from
https://gcc.gnu.org/legacy-ml/gcc-patches/1999-04n/msg00719.html

Support of extended syntax is nice, espcially that this is also supported by
Clang and MSVC. However, there's a key difference between GCC and Clang/MSVC:
GCC doesn't expand macros in #pragma pack.

That means, given following code widely used in MinGW-w64 headers
```
#define _CRT_PACKING 8
#pragma pack(push,_CRT_PACKING)
```
Clang/MSVC all treat it as `#pragma pack(push, 8)`, while GCC treats
_CRT_PACKING as the <id>, and [n] left empty, which defaults to 0 then.

I think this behavior is quite counterintuitive and dangerous. Currently I got
2 ideas to mitigate:
1. Warn if <id> is an macro. Not sure whether this is easy to implement due to
translation stages.
2. Warn if <id> is given, but <n> is left empty.

It may be better if GCC can do macro expansion in #pragma pack, though I'm not
sure if this breaks existing code. Currently the only solution to use macros in
#prgama pack on GCC is something like:
```
#define __MINGW_PRAGMA_PARAM_IMPL(x) _Pragma (#x)
#define __MINGW_PRAGMA_PARAM(x) __MINGW_PRAGMA_PARAM_IMPL(x)

__MINGW_PRAGMA_PARAM(pack(push, _CRT_PACKING))
```

Reply via email to