How to use alignas to replace pragma pack?

时间秒杀一切 提交于 2021-02-06 15:15:43

问题


I am trying to understand how alignas should be used, I wonder if it can be a replacement for pragma pack, I have tried hard to verify it but with no luck. Using gcc 4.8.1 (http://ideone.com/04mxpI) I always get 8 bytes for below STestAlignas, while with pragma pack it is 5 bytes. What I would like ot achive is to make sizeof(STestAlignas) return 5. I tried running this code on clang 3.3 (http://gcc.godbolt.org/) but I got error:

!!error: requested alignment is less than minimum alignment of 8 for type 'long' - just below alignas usage.

So maybe there is a minimum alignment value for alignas?

below is my test code:

#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;
}

results for gcc 4.8.1:

pragma pack = 5
attribute packed = 5
alignas = 8

[26.08.2019]

It appears there is some standardisation movement in this topic. p1112 proposal - Language support for class layout control - suggest adding (among others) [[layout(smallest)]] attribute which shall reorder class members so as to make the alignment cost as small as possible (which is a common technique among programmers - but it often kills class definition readability). But this is not equal to what pragma(pack) does!


回答1:


alignas cannot replace #pragma pack.

GCC accepts the alignas declaration, but still keeps the member properly aligned: satisfying the strictest alignment requirement (in this case, the alignment of long) also satisfies the requirement you specified.

However, GCC is too lenient as the standard actually explicitly forbids this in §7.6.2, paragraph 5:

The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers were omitted (including those in other declarations).




回答2:


I suppose you know that working with unaligned or missaligned data have risks and have costs.

For instance, retrieving a missaligned Data Structure of 5 bytes is more time-expensive than retrieving an 8 bytes aligned one. This is because, if your 5 "... byte data does not start on one of those 4 byte boundaries, the computer must read the memory twice, and then assemble the 4 bytes to a single register internally" (1).

Working with unaligned data requires more mathematical operations and ends in more time (and power) consumption by the ECU.

Please, consider that both C and C++ are conceived to be "hardware friendly" languages, which means not only "minimum memory usage" languages, but principally languages focused on efficiency and fastness processing. Data alignmnt (when it is not strictly required for "what I need to store") is a concept that implies another one: "many times, software and hardware are similar to life: you require sacrifices to reach better results!".

Please, consider also asking yourself is you do not have a wrong assumption. Something like: "smaller/st structures => faster/st processing". If this were the case, you might be (totally) wrong.

But if we suppose that your point is something like this: you do not care at all about efficiency, power consumption and fastness of your software, but just you are obsessed (because of your hardware limitations or just because of theoritcal interest) in "minimum memory usage", then and perhaps you might find useful the following readings:

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

(2) C Avoiding Alignment Issues

BUT, please, be sure to read the following ones:

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

Which redirects to this Standard's snipped:

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

(5) Unaligned memory access: is it defined behavior or not? [Which is duplicated but, maybe, with some extra information].




回答3:


Unfortunately, alignment is not guaranted, neither in C++11 nor in C++14. But it is effectived guaranted in C++17.

Please, check this excellent work from Bartlomiej Filipek:

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



来源:https://stackoverflow.com/questions/18978006/how-to-use-alignas-to-replace-pragma-pack

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!