0

使用以前的 gcc 编译器,我们这样做了:

#define DO_PRAGMA(x)        _Pragma(#x)
#define PACK_ON(n)          DO_PRAGMA(pack(n))

所以实际上意味着 PACK_ON(2) 将扩展为 _Pragma(pack(2)) 然后我们会像这样使用它

PACK_ON(2)
typedef struct{
...
};

但是,IAR 编译器想要这样的东西: _Pragma("pack(2)") 所以我尝试通过以下非编译方式来实现 pack 的宏:

#define DO_PRAGMA(x)        _Pragma(#x)
#define PACK_ON(n)          DO_PRAGMA(" ## "pack(#n)"" ## ")
#define PACK_ON(n)          DO_PRAGMA(" ## pack(#n) ## ")
#define PACK_ON(n)          DO_PRAGMA(" ## #pack(n) ## ")
#define PACK_ON(n)          DO_PRAGMA(" ## #pack(n) ## ")
#define PACK_ON(n)          DO_PRAGMA("pack(n)")
#define PACK_ON(n)          DO_PRAGMA("pack(#n)")
#define PACK_ON(n)          DO_PRAGMA(pack(#n))
#define PACK_ON(n)          DO_PRAGMA(pack(n))
#define PACK_ON(n)          DO_PRAGMA(#pack(#n))
#define PACK_ON(n)              \#if (n == 1)\ _Pragma("pack(1)")
#define PACK_ON(n)          _Pragma("pack( ## #n ## )")
#define PACK_ON(n)          _Pragma("pack( ## n ## )")
#define PACK_ON(n)          _Pragma("pack(n)")
#define PACK_ON(n)          _Pragma("pack(#n)")

有没有人有一个宏可以与 IAR 编译器一起使用来打包各种大小的 n ?如果不是,我将强制所有内容打包大小 1 并手动更改使用 2 和 4 的结构。

临时解决方案:我已经设法通过这样做来解决这个问题:

#define PACK_ON(n)              _Pragma("pack(1)")

并手动更改 PACK_ON(2) 和 PACK_ON(4) 的一小部分

4

2 回答 2

1

鉴于编译器支持pack(1),pushpoppragma,那么这个标准 C 解决方案可以工作:

#include <stdio.h>

#define DO_PRAGMA(x)        _Pragma(#x)
#define PACK_ON(n)          _Pragma("pack(push)") DO_PRAGMA(pack(n))
#define PACK_OFF            _Pragma("pack(pop)")

PACK_ON(1)
typedef struct 
{
  char c;
  short s;
} foo;
PACK_OFF

typedef struct 
{
  char c;
  short s;
} bar;


int main()
{ 
  printf("%zu\n", sizeof(foo));
  printf("%zu\n", sizeof(bar));
}

输出

3
4

在 gcc、clang 和 icc 上进行了严格的标准设置 ( -std=c11 -pedantic-errors) 测试。

于 2021-03-04T13:48:56.137 回答
0

使用上面的 PACK_ON 我得到错误标识符“pack”未定义。我已经设法通过这样做来解决这个问题:#define PACK_ON(n) _Pragma("pack(1)") 并手动更改少数 PACK_ON(2) 和 PACK_ON(4)

于 2021-03-16T14:51:01.973 回答