C++11 and Alignment

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
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
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
Did you try writing alignas(2) at the start of line 5?

I'm actually not sure that requesting specific alignment will eliminate padding.
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.
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)
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.
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.