How to use alignas to replace pragma pack?
Asked Answered
B

3

18

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!

Basis answered 24/9, 2013 at 9:40 Comment(1)
I think #pragma pack will forever be a non-portable extension. Some architectures don't support unaligned memory accesses.Crompton
C
18

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).

Crompton answered 24/9, 2013 at 9:43 Comment(0)
F
3

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].

Faber answered 24/8, 2019 at 20:35 Comment(1)
:-) thank You for all those ideas - I'Am all aware of them. Both your answers are off-topic to my question.Basis
F
1

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

Faber answered 23/8, 2019 at 3:2 Comment(1)
This new feature if for overaligned data (for dynamic allocation), I would use it if I would like to place my data at specified address alignment (i.e. divisible by 128). My question was how to - let-s call it - under-align data, so to make is as small as possible by eliminating alignment of particular structure fields.Basis

© 2022 - 2024 — McMap. All rights reserved.