Search code examples
c++visual-studiomacrosnamespacespacked

C++ Macro takes proceeding code to be out of namespace


Currently I have a program which need attribute packing for numerous functions. The code must be interchangeable between Windows Visual Studio C++ and GCC C++. Currently it is very hard to read and I wanted to clean it up with a C++ macro, however, I noticed that after I use the macro once, the next lines of code exit the current namespace. Is there a way to fix this? Here is sample code similar to what I am working on and images of the problem.

#if defined(_WIN32) || defined(_WIN64)
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#else
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif

namespace test {
  PACK(typedef struct temp1 {
    int a;
    int b;
  });

  PACK(typedef struct temp2 {
    int c;
    int d;
  });
}

enter image description hereenter image description here

In visual studio, when my cursor is in the 1st struct, VS shows it is within the namespace test, however, the 2nd in the global namespace. Any ideas on what would fix this?

As of now my structs look more like the code below, which works, but it makes it much harder to read especially with 100+ of these packed structs.

#define PACK __attribute__((__packed__))

namespace test {
  #if defined(_WIN32) || defined(_WIN64)
  #pragma pack(push, 1)
  #endif
  typedef struct temp1 {
    int a;
    int b;
  }
  #if defined(_WIN32) || defined(_WIN64)
  temp2;
  #pragma pack(pop)
  #else
  PACK temp2;
  #endif

  #if defined(_WIN32) || defined(_WIN64)
  #pragma pack(push, 1)
  #endif
  typedef struct temp2 {
    int c;
    int d;
  }
  #if defined(_WIN32) || defined(_WIN64)
  temp2;
  #pragma pack(pop)
  #else
  PACK temp2;
  #endif
}

Solution

  • There is no need to typedef a struct declaration in C++. That is only needed in C, if you don't want to use the struct keyword every place a struct type is used (variables, function parameters, etc).

    In Visual Studio, it would be easier to just put a single #pragma pack(push, 1) before the first struct declaration, and a single #pragma pack(pop) after the last struct declaration. You don't need to pack the structs individually.

    On GCC, you can skip the #pragma and just use __attribute__((packed)) on each struct declaration.

    Try something more like this:

    #ifdef __GNUC__
    #define PACKED_ATTR __attribute__ ((__packed__))
    #else
    #define PACKED_ATTR
    #endif
    
    namespace test {
      #ifdef _MSC_VER
      #pragma pack(push, 1) // or: #include <pshpack1.h>
      #endif
    
      struct PACKED_ATTR temp1 {
        int a;
        int b;
      };
    
      struct PACKED_ATTR temp2 {
        int c;
        int d;
      };
    
      // and so on ...
    
      #ifdef _MSC_VER
      #pragma pack(pop) // or: #include <poppack.h>
      #endif
    }