在 Borland C++ 上使用#pragma pack 和#define
Use #pragma pack with #define on Borland C++
我正在尝试用 Borland C++Builder (XE6) 打包一些结构(将来:bcc)。
我正在使用一个库,它使用以下构造来创建结构:
#ifdef _MSC_VER
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#endif
PACKED_BEGIN
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
PACKED_END
bcc 编译器不喜欢 MSC __pragma
,也不喜欢宏内部的预处理器指令,尽管在 their website 中有描述:
#define GETSTD #include <stdio.h>
我的问题是:是否有可能将此构造与 Borland 编译器一起用于打包结构 而无需 使用:
#pragma pack(1)
打包每个结构?
是否有任何解决方法?
该标准为编写编译指示提供了一种额外的选择:_Pragma
运算符:
#define PACKED_BEGIN _Pragma("pack(push, 1)")
#define PACKED
#define PACKED_END _Pragma("pack(pop)")
如果 Borland 编译器支持,应该可以。
如您所述,C++Builder 不支持宏内部的预处理器语句。这记录在 Embarcadero 的网站上:
After each individual macro expansion, a further scan is made of the newly expanded text. This allows for the possibility of nested macros: The expanded text can contain macro identifiers that are subject to replacement. However, if the macro expands into what looks like a preprocessing directive, the directive will not be recognized by the preprocessor.
这是因为宏中的 #
字符是为预处理器的 字符串化运算符 .
保留的
一些编译器(包括 MSVC)通过 __pragma()
编译器扩展或 C99/C++x0 _Pragma()
扩展来绕过该限制。 C++Builder 的 Windows 32 位 编译器不支持其中任何一个。但是,其Windows 64bit和mobile编译器(均基于clang,支持C++11)DO 支持它们。所以你可以像这样在宏中添加对这些编译器的支持:
#if defined(__BORLANDC__)
#if defined(__clang__)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#else
#error Cannot define PACKED macros for this compiler
#endif
#elif defined(_MSC_VER)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#else
#error PACKED macros are not defined for this compiler
#endif
如果您想支持 C++Builder Windows 32 位 编译器,您必须将逻辑移动到使用 [=20= 的 .h 文件中] ,然后你可以 #include
那些需要的文件(至少在编译器更新为支持 clang/C++11 之前 - Embarcadero 目前正在处理):
pack1_begin.h:
#if defined(__BORLANDC__)
#define PACKED_BEGIN
#define PACKED
#define PACKED_END
#pragma pack(push, 1)
#elif defined(_MSC_VER)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#else
#error PACKED macros are not defined for this compiler
#endif
pack_end.h:
#if defined(__BORLANDC__)
#pragma pack(pop)
#endif
那么你可以这样做:
#include "pack1_begin.h"
PACKED_BEGIN
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
PACKED_END
#include "pack_end.h"
如果采用这种方法,则可以完全删除 PACKED_BEGIN
/PACKED_END
:
pack1_begin.h:
#if defined(__BORLANDC__) || defined(_MSC_VER)
#define PACKED
#pragma pack(push, 1)
#elif defined(__GNUC__)
#define PACKED __attribute__((__packed__))
#else
#error PACKED macro is not defined for this compiler
#endif
pack_end.h:
#if defined(__BORLANDC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#include "pack1_begin.h"
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
#include "pack_end.h"
我正在尝试用 Borland C++Builder (XE6) 打包一些结构(将来:bcc)。
我正在使用一个库,它使用以下构造来创建结构:
#ifdef _MSC_VER
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#endif
PACKED_BEGIN
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
PACKED_END
bcc 编译器不喜欢 MSC __pragma
,也不喜欢宏内部的预处理器指令,尽管在 their website 中有描述:
#define GETSTD #include <stdio.h>
我的问题是:是否有可能将此构造与 Borland 编译器一起用于打包结构 而无需 使用:
#pragma pack(1)
打包每个结构?
是否有任何解决方法?
该标准为编写编译指示提供了一种额外的选择:_Pragma
运算符:
#define PACKED_BEGIN _Pragma("pack(push, 1)")
#define PACKED
#define PACKED_END _Pragma("pack(pop)")
如果 Borland 编译器支持,应该可以。
如您所述,C++Builder 不支持宏内部的预处理器语句。这记录在 Embarcadero 的网站上:
After each individual macro expansion, a further scan is made of the newly expanded text. This allows for the possibility of nested macros: The expanded text can contain macro identifiers that are subject to replacement. However, if the macro expands into what looks like a preprocessing directive, the directive will not be recognized by the preprocessor.
这是因为宏中的 #
字符是为预处理器的 字符串化运算符 .
一些编译器(包括 MSVC)通过 __pragma()
编译器扩展或 C99/C++x0 _Pragma()
扩展来绕过该限制。 C++Builder 的 Windows 32 位 编译器不支持其中任何一个。但是,其Windows 64bit和mobile编译器(均基于clang,支持C++11)DO 支持它们。所以你可以像这样在宏中添加对这些编译器的支持:
#if defined(__BORLANDC__)
#if defined(__clang__)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#else
#error Cannot define PACKED macros for this compiler
#endif
#elif defined(_MSC_VER)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#else
#error PACKED macros are not defined for this compiler
#endif
如果您想支持 C++Builder Windows 32 位 编译器,您必须将逻辑移动到使用 [=20= 的 .h 文件中] ,然后你可以 #include
那些需要的文件(至少在编译器更新为支持 clang/C++11 之前 - Embarcadero 目前正在处理):
pack1_begin.h:
#if defined(__BORLANDC__)
#define PACKED_BEGIN
#define PACKED
#define PACKED_END
#pragma pack(push, 1)
#elif defined(_MSC_VER)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#else
#error PACKED macros are not defined for this compiler
#endif
pack_end.h:
#if defined(__BORLANDC__)
#pragma pack(pop)
#endif
那么你可以这样做:
#include "pack1_begin.h"
PACKED_BEGIN
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
PACKED_END
#include "pack_end.h"
如果采用这种方法,则可以完全删除 PACKED_BEGIN
/PACKED_END
:
pack1_begin.h:
#if defined(__BORLANDC__) || defined(_MSC_VER)
#define PACKED
#pragma pack(push, 1)
#elif defined(__GNUC__)
#define PACKED __attribute__((__packed__))
#else
#error PACKED macro is not defined for this compiler
#endif
pack_end.h:
#if defined(__BORLANDC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#include "pack1_begin.h"
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
#include "pack_end.h"