C++ 在Borland C和x2B上使用带有“define”的“pragma包”+;
我正在尝试用Borland C++Builder(XE6)(将来:bcc)打包一些结构 我使用的库使用以下构造创建结构:C++ 在Borland C和x2B上使用带有“define”的“pragma包”+;,c++,c++builder,pragma,borland-c++,C++,C++builder,Pragma,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
#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\uuu pragma
,也不喜欢宏内部的预处理器指令,尽管在以下章节中有描述:
打包每个结构
有什么解决方法吗?该标准提供了一个额外的用于编写Pragma的替代方法:
\u Pragma
操作符:
#define PACKED_BEGIN _Pragma("pack(push, 1)")
#define PACKED
#define PACKED_END _Pragma("pack(pop)")
如果Borland编译器支持它,它应该可以工作。如您所述,C++Builder不支持宏内部的预处理器语句。这记录在Embarcadero的网站上: 每次宏展开后,对新展开的文本进行进一步扫描。这允许嵌套宏的可能性:扩展文本可以包含需要替换的宏标识符但是,如果宏扩展为类似预处理指令的内容,则预处理器将无法识别该指令。 原因是宏中的
#
字符是为预处理器的字符串化操作符保留的
一些编译器,包括MSVC,通过\uu pragma()
编译器扩展或C99/C++x0\u pragma()
扩展绕过了这一限制。C++Builder的Windows 32位编译器不支持这两种类型。但是,它的Windows 64位和mobile编译器(都基于clang并支持C++11)确实支持这两种编译器。因此,您可以在宏中添加对这些编译器的支持,如下所示:
#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++BuilderWindows 32位编译器,您必须将逻辑移到使用#pragma
的.h文件中,然后您可以#在需要的地方包含这些文件(至少在编译器更新为支持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
#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
包装结束。h:
#if defined(__BORLANDC__)
#pragma pack(pop)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
#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\u BEGIN
/PACKED\u END
一起删除:
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
#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
包装结束。h:
#if defined(__BORLANDC__)
#pragma pack(pop)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
您仍然可以使用#include“packed_begin.h”
和#include“packed_end.h”
(无防护装置)谢谢您的评论,但我不能在宏中使用#include,因为borland不支持此功能。我可以重写图书馆,但我希望有可能macros@user2358582好吧,它不应该,它不是合法的C++。我相信Jarod的意思是你可以用它替换宏行。是的,我只是认为有可能不编辑库文件。我只是可以做preg_replace,但是当库更新时,我必须再做一次。对于宏,我只能使用新文件,它仍然可以编译。谢谢您的回答,但不幸的是,Borland编译器(我的版本)不支持_Pragma。@user2358582:C++Builder的32位编译器不支持,但是它的64位和移动编译器都做了。我只想补充一句,C++编译器不能支持宏替换中的指令。C++11 16.34./3:“生成的完全由宏替换的预处理令牌序列不作为预处理指令处理,即使它类似于预处理指令,…”