C++11 and Alignment

Feb 20, 2014 at 4:50pm
I'm trying to use alignas, but it feels like it's being silently ignored.

I'm supposed to have a BITMAPFILEHEADER struct manually declared to avoid dependencies, but it has a 4-byte alignment requirement, and reading directly file to struct gives bad values.

Forcing alignment to 2-byte (alignas) doesn't seem to work, reading from the "original" BITMAPFILEHEADER works correctly, but makes use of

1
2
3
#pragma pack(push,2)
struct /*...*/;
#pragma pack(pop) 


Testcase:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <ifstream>
#include <ios>

struct BITMAPFILEHEADERx {
  unsigned short  bfType;
  unsigned long bfSize;
  unsigned short  bfReserved1;
  unsigned short  bfReserved2;
  unsigned long bfOffBits;
};

int main() {
  std::ifstream file;
  file.open("test.bmp",std::ios::in|std::ios::binary);
  
  alignas(2) BITMAPFILEHEADERx bfh;
  file.read((char*)&bfh,sizeof(bfh));
  
  if(bfh.bfType != 0x4D42)
      return 1;// incorrect format
  
  std::cout << bfh.bfOffBits << std::endl;
  std::cin.get();
  return 0;
}


The testcase is supposed to output a tiny number, usually 54.

MinGW/G++ 4.8.1 .

Doing something wrong?
Last edited on Feb 20, 2014 at 4:50pm
Feb 20, 2014 at 4:55pm
bfh will be aligned to a 2 byte boundary, the elements of the struct that happen to make up bfh are not relatively affected in any way. Otherwise the alignas would be part of the type information! What a mess that would be!

http://en.cppreference.com/w/cpp/language/alignas
Last edited on Feb 20, 2014 at 4:56pm
Feb 20, 2014 at 4:59pm
So I should write alignas for each element in the struct?
The example over there doesn't seem to do anything, neither writing alignas(2) over everything.

I accidentally wrote I resolved the issue, but I used the older structure.
Last edited on Feb 20, 2014 at 5:01pm
Feb 20, 2014 at 5:04pm
Did you try writing alignas(2) at the start of line 5?

I'm actually not sure that requesting specific alignment will eliminate padding.
Feb 20, 2014 at 5:09pm
note: attribute for 'struct BITMAPFILEHEADERx' must follow the 'struct' keyword


And, same result anyways.
I think I'll have to read and write all the variables one by one.
Feb 20, 2014 at 5:19pm
it has a 4-byte alignment requirement, and reading directly file to struct gives bad values. Forcing alignment to 2-byte (alignas) doesn't seem to work,


You cannot weaken the alignment with alignas (see the cppreference link above or §7.6.2[dcl.align]/5)
Feb 20, 2014 at 5:24pm
You could always go the array-and-reference route - make an array of the correct size, read into it, and have your structure automatically make its reference members refer to the correct locations in the array.

Also if you're so concerned about padding and data alignment I am surprised you're using the raw primitive types - you should be using std::uint16_t and std::uint32_t.
Feb 20, 2014 at 7:43pm
It was just for testing, I am aware of those types, I'm supposed to use DDS but began the tests with BMP's.
Topic archived. No new replies allowed.