Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Borland C和x2B上使用带有“define”的“pragma包”+;_C++_C++builder_Pragma_Borland C++ - Fatal编程技术网

C++ 在Borland C和x2B上使用带有“define”的“pragma包”+;

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

我正在尝试用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
\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:“生成的完全由宏替换的预处理令牌序列不作为预处理指令处理,即使它类似于预处理指令,…”