两个成员都是位标志的大小相同的类之间的实际差异
Practical differences between 2 class of the same size whose members are all bitflags
一般来说,在C++中,类的大小是其成员的聚合大小,包括任何基类成员。
这样定义的两个类之间的实际区别是什么,它们的成员都表示位标志:
class A { // 16 bytes
uint64_t x;
uint64_t y;
};
class B { // 16 bytes
uint64_t x;
uint32_t y;
uint16_t z;
uint8_t r;
uint8_t s;
};
我能想到的是:
B的数据可以更细粒度地访问,而无需执行逐位操作。例如,要访问A中等效的B::r,您必须执行以下操作:
(a.y & 0xFF00) >> 8; // b.r
- 从语义上讲,不同的成员意味着这些成员的数据属于类的不同概念。即:"年龄"与"长度"是不同的概念
我认为两个类上的东西都是一样的:
- 内存布局
我不知道的事情:
- 如何在两个类之间影响CPU缓存
- 在对这两个类的成员执行逐位操作时,任何速度差
问题的答案在很大程度上取决于目标平台,尤其是其应用程序二进制接口(ABI)。您可以在此处检查X86-64 System V ABI(Windows有不同的ABI):
https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
ABI管理结构布局(以及许多其他事项),正如Sam所提到的,两个结构的布局不能保证相同。对于X86-64,它们恰好是相同的,但对于其他目标,可能会引入字段之间的填充。
字段本身的访问方式也取决于目标体系结构,即可用于进行加载和存储的指令。存在许多不直接支持字节大小的存储器访问的机器,因此字段r和s将在更宽的负载后通过移位来访问。编译器有责任为字段访问操作生成正确的代码。
同样可以理解的是,一些机器可能有足够宽的寄存器来容纳整个结构,这意味着访问任何字段都需要一些位处理。实际上,X86-64 ABI指定了函数调用语义,该语义将两个寄存器中的任何一个结构传递给被调用者,然后被调用者需要提取数据,很可能会将数据推送到堆栈上以便在函数中进行访问。
对于几乎所有现实世界中的应用程序,这些细节都无关紧要,任何一种结构布局都可以正常工作。从程序员的角度来看,第二种方法最好假设字段对应于程序中的逻辑概念。读取简单的字段访问比位偏移和字段访问的掩码容易得多。
当然,某些应用程序非常关心布局、性能、空间问题或系统之间的互操作性。
- 给定两个偶数,求出它们之间所有偶数的平方和
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 如何在两个 boost::multi_arrays (C++) 之间执行数学运算?
- 查找字符在两个索引之间出现的次数
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- C++两个源文件之间共享的枚举的静态实例
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 以天C++为单位的两个时间戳之间的差异
- 将向量之间的数字放在另一个向量之间<vector>>如果两个数字的差值为 1
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- 通过插槽和信号在不同线程中的两个qt对象之间进行通信
- 在C++中查找两个向量之间最相似的值
- 两个有符号数字之间的距离
- Directx 12 :在两个进程之间共享图形内存
- 如何找到两个日期之间的时间差异(以秒和纳秒为单位)?
- 是否有一种标准方法来计算两个 asctime() 值之间的天数
- 如何找到两个棋盘平面之间的角度?
- 计算两个迭代器之间的距离时"Vector Iterators Incompatible"
- 使用 Dijkstra 算法跟踪两个节点之间的最短路径
- 无法理解代码背后的逻辑,这是在两个给定数字之间生成素数的优化问题