使用bool导出打包结构
Exporting Packed structures with bool
导出包含布尔值的打包结构的最佳实践是什么?
我问这个问题是因为我试图找到最好的方法。当前I do:
#ifndef __cplusplus
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h> //size is 1.
#else
typedef enum {false, true} bool; //sizeof(int)
#endif
#endif
现在在上面,布尔值的大小可以是1或sizeof(int)
..
在这样的结构中:
#pragma pack(push, 1)
typedef struct
{
long unsigned int sock;
const char* address;
bool connected;
bool blockmode;
} Sock;
#pragma pack(pop)
如果使用C与C99 &c++。如果我把它导出为一个整数,那么布尔值为1的语言就有对齐问题,需要填充结构。
我想知道在c99之前的情况下,是否最好将bool类型定义为char类型,但感觉不对。
有更好的主意吗?
这取决于你在寻找什么:保留空间但运行一些额外的指令,或者浪费一些字节但运行得更快。
如果你希望更快,但可能会"浪费"几个字节的空间(即每个布尔标志一个值,参见sizeof bool讨论),你目前的方法是优越的。这是因为它可以直接加载和比较布尔值,而不必在打包字段中屏蔽它们(见下一节)。
如果你想节省空间,那么你应该看看C位域:
struct Sock {
...
int connected:1; // For 2 flags, you could also use char here.
int blockmode:1;
}
或滚动你自己的"标志",并将位设置为整数值:
#define SOCKFLAGS_NONE 0
#define SOCKFLAGS_CONNECTED (1<<0)
#define SOCKFLAGS_BLOCKMODE (1<<1)
struct Sock {
...
int flags; // For 2 flags, you could also use char here.
}
这两个例子或多或少导致相同的代码,掩盖位和移位值(额外的指令),但比简单的bool
值更密集的包装。
我认为,使用#pragma pack
的痛苦(长期)大于收益(短期)。
-
这是编译器特定的;
-
我了解嵌入式系统或协议的场景。只需要一点点额外的努力,代码就可以被编写为无pragma的。
-
我也想尽可能多地包装我的结构,并像您那样以更宽的优先方式布局成员。然而,我不介意损失2个字节,如果这允许我的代码符合标准和可移植的话。
我会做以下三件事:
- 将标志声明为
bool
(您已经这样做了)并分配true/false
- 把他们作为
struct
的最后成员(你已经这样做了) - 使用位域(根据其他堆栈者的建议)
:
typedef struct Sock
{
long unsigned int sock;
const char* address;
bool connected : 1;
bool blockmode : 1;
} Sock;
在c99之前的情况下,对typedef char bool;
有风险。这会静默地破坏如下代码:
bool x = (foo & 0x100);
如果foo
中设置了该位,则应该将x
设置为真。enum也有同样的问题
在我的代码中,我实际上做typedef unsigned char bool;
,但然后我小心地在表达式转换为bool
的地方编写!!
。这并不理想。
根据我的经验,在整型中使用标志比在C90的结构中使用bool
或位域导致的问题更少。
- 是否可以使用智能指针成员设置具有另一个结构的结构?
- 如何创建结构的结构结构,等等嵌套多个结构?
- 继承或结构到结构
- 结构内部结构的联合 - 混合 C 和 C++
- 通过指针算法调用结构的结构属性
- Rcpp - 在包结构之外编译
- 包含打包结构的结构是否自行打包?
- C++ - 候选函数不可行:没有从"结构"到"结构(&)"的已知转换
- TCP-Server以数据包结构(非Java客户端)发送文件
- C++包含结构的结构 SIGSEGV
- C 嵌套的数据结构利用结构
- 使用包含该结构内部结构的 using 定义
- 是否可以定义一个在外部"C"块中继承另一个结构的结构?
- 将复杂的结构(带有结构的内部数组)从 C# 传递到C++
- C# TCP 数据包结构
- 如何在我的代码中获取相同结构的结构中的引用
- 如何在类中添加结构,结构的向量以映射
- Python扩展模块包结构(命名空间)
- 在嵌入式python 3中以编程方式定义包结构
- 从Debian包结构中的程序中访问资源