【问题标题】:How to use alignas to replace pragma pack?如何使用 alignas 替换 pragma pack?
【发布时间】:2013-09-29 10:57:18
【问题描述】:

我正在尝试了解应该如何使用 alignas,我想知道它是否可以替代 pragma pack,我已经努力验证它但没有运气。使用 gcc 4.8.1 (http://ideone.com/04mxpI) 我总是得到低于 STestAlignas 的 8 个字节,而使用 pragma pack 它是 5 个字节。我想要实现的是让 sizeof(STestAlignas) 返回 5。我尝试在 clang 3.3 (http://gcc.godbolt.org/) 上运行此代码,但出现错误:

!!错误:对于“long”类型,请求的对齐小于 8 的最小对齐 - 刚好低于 alignas 的使用。

那么也许 alignas 有一个最小对齐值?

下面是我的测试代码:

#include <iostream>
#include <cstddef>
using namespace std;

#pragma pack(1)
struct STestPragmaPack {
  char c;
  long d;
} datasPP;
#pragma pack()

struct STestAttributPacked {
  char c;
  long d;
} __attribute__((packed)) datasAP;

struct STestAlignas {
  char c;
  alignas(char) long d;
} datasA;

int main() {
    cout << "pragma pack = " << sizeof(datasPP) << endl;
    cout << "attribute packed = " << sizeof(datasAP) << endl;
    cout << "alignas = " << sizeof(datasA) << endl;
}

gcc 4.8.1 的结果:

pragma pack = 5
attribute packed = 5
alignas = 8

[26.08.2019]

似乎在这个主题中有一些标准化运动。 p1112 提案 - Language support for class layout control - 建议添加(除其他外)[[layout(smallest)]] 属性,该属性应重新排序类成员,以使对齐成本尽可能小(这是程序员中的常用技术 - 但它通常会破坏类定义的可读性) .但这等于 pragma(pack) 所做的!

【问题讨论】:

  • 我认为#pragma pack 将永远是一个不可移植的扩展。某些架构不支持未对齐的内存访问。

标签: c++ gcc c++11 alignas


【解决方案1】:

alignas 不能替换 #pragma pack

GCC 接受 alignas 声明,但仍保持成员正确对齐:满足最严格的对齐要求(在本例中,long 的对齐)也满足您指定的要求。

但是,GCC 过于宽松,因为标准实际上在 §7.6.2 第 5 段中明确禁止这样做:

声明中所有 alignment-specifiers 的组合效果不应指定比所有 alignment-specifiers 声明的实体所需的对齐更严格的对齐方式 被省略了(包括那些在其他声明中的)。

【讨论】:

    【解决方案2】:

    我想您知道使用未对齐或未对齐的数据存在风险和成本。

    例如,检索 5 字节未对齐的数据结构比检索 8 字节对齐的数据结构更耗时。这是因为,如果您的 5“...字节数据不是从这 4 个字节边界之一开始,计算机必须读取内存两次,然后在内部将 4 个字节组装到单个寄存器”(1)。

    处理未对齐的数据需要更多的数学运算,并最终导致 ECU 消耗更多的时间(和功率)。

    请注意,C 和 C++ 都被认为是“硬件友好”语言,这不仅意味着“最小内存使用”语言,而且主要是专注于效率和快速处理的语言。数据对齐(当它不是严格要求“我需要存储什么”时)是一个概念,它暗示了另一个概念:“很多时候,软件和硬件就像生活一样:你需要牺牲才能达到更好的结果!”。

    请考虑问问自己是否有错误的假设。类似于:“更小/st 结构 => 更快/st 处理”。如果是这样的话,你可能(完全)错了。

    但是如果我们假设你的观点是这样的:你根本不关心软件的效率、功耗和速度,而只是你痴迷(因为你的硬件限制或只是因为理论上的兴趣)在“最小内存使用”中,也许您会发现以下读数有用:

    (1)Declare, manipulate and access unaligned memory in C++

    (2)C Avoiding Alignment Issues

    但是,请务必阅读以下内容:

    (3)What does the standard say about unaligned memory access?

    重定向到本标准的片段:

    (4)http://eel.is/c++draft/basic.life#1

    (5) Unaligned memory access: is it defined behavior or not? [这是重复的,但可能包含一些额外信息]。

    【讨论】:

    • :-) 谢谢你的所有这些想法——我都知道它们。您的两个答案都与我的问题无关。
    【解决方案3】:

    不幸的是,对齐并不能保证,无论是在 C++11 中还是在 C++14 中但在 C++17 中保证有效

    请查看 Bartlomiej Filipek 的出色作品:

    https://www.bfilipek.com/2019/08/newnew-align.html

    【讨论】:

    • 这个新功能如果用于过度对齐的数据(用于动态分配),如果我想将我的数据放在指定的地址对齐位置(即可被 128 整除),我会使用它。我的问题是如何 - 让我们称之为 - 欠对齐数据,因此通过消除特定结构字段的对齐来尽可能小。
    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 2017-01-14
    • 2016-01-15
    • 1970-01-01
    • 2014-05-10
    • 2015-03-24
    • 2015-06-20
    • 2012-07-09
    相关资源
    最近更新 更多