0

In an attempt to understand C memory alignment or whatever the term is (data structure alignment?), i'm trying to write code that results in a alignment error. The original reason that brought me to learning about this is that i'm writing data parsing code that reads binary data received over the network. The data contains some uint32s, uint64s, floats, and doubles, and i'd like to make sure they are never corrupted due to errors in my parsing code.

An unsuccessful attempt at causing some problem due to misalignment:

uint32_t integer = 1027;
uint8_t * pointer = (uint8_t *)&integer;
uint8_t * bytes = malloc(5);
bytes[0] = 23; // extra byte to misalign uint32_t data
bytes[1] = pointer[0];
bytes[2] = pointer[1];
bytes[3] = pointer[2];
bytes[4] = pointer[3];
uint32_t integer2 = *(uint32_t *)(bytes + 1);
printf("integer: %u\ninteger2: %u\n", integer, integer2);

On my machine both integers print out the same. (macbook pro with Intel 64 bit processor, not sure what exactly determines alignment behaviour, is it the architecture? or exact CPU model? or compiler maybe? i use Xcode so clang)

I guess my processor/machine/setup supports unaligned reads so it takes the above code without any problems.

What would a case where parsing of say an uint32_t would fail because of code not taking alignment in account? Is there a way to make it fail on a modern Intel 64 bit system? Or am i safe from alignment errors when using simple datatypes like integers and floats (no structs)?

Edit: If anyone's reading this later, i found a similar question with interesting info: Mis-aligned pointers on x86

Community
  • 1
  • 1
quad16
  • 184
  • 5
  • 20
  • 7
    There are no alignment requirements on x86. It help for performance but it is not required. – Jonathon Reinhart Aug 28 '16 at 21:31
  • Ok, so i can toss around byte arrays and uint32s floats doubles uint64s and never ever have any corruption? – quad16 Aug 28 '16 at 21:34
  • That's not a particularly specific question. As I said, there is nothing you can do as far as alignment of datatypes go that will cause an error. – Jonathon Reinhart Aug 28 '16 at 21:35
  • I mean, is there any risk to run into data corruption because of alignment issues on x86? edit: oh ok that would be nice if it is so – quad16 Aug 28 '16 at 21:36
  • It's just that i read other people [talking](http://stackoverflow.com/questions/13881487/should-i-worry-about-the-alignment-during-pointer-casting) about about alignment problems and i want to understand when to worry about this. Would you know about ARM (iPhone) too, is it safe to not worry about alignment there too? – quad16 Aug 28 '16 at 22:02
  • RISC chips often generate SIGBUS when asked to access misaligned data. Back in the day, the DEC Alpha would generate an error and run a kernel interrupt handler routine to patch the misaligned access up. That was a *lot* slower than not needing to going into an interrupt handler. You could control whether it did that with the `uac` (unaligned access control) command. The penalty for handling consistent and frequent misaligned access was dramatic. – Jonathan Leffler Aug 28 '16 at 22:25
  • Note that `"%u"` is not necessarily the right specifier for `uint32_t integer ... printf("integer: %u\n", integer);` – chux - Reinstate Monica Aug 29 '16 at 01:50

1 Answers1

1

Normally, the x86 architecture doesn't have alignment requirements [except for some SIMD instructions like movdqa).

However, since you're trying to write code to cause such an exception ...

There is an alignment check exception bit that can be set into the x86 flags register. If you turn in on, an unaligned access will generate an exception which will show up [under linux at least] as a bus error (i.e. SIGBUS)

See my answer here: any way to stop unaligned access from c++ standard library on x86_64? for details and some sample programs to generate an exception.

Community
  • 1
  • 1
Craig Estey
  • 30,627
  • 4
  • 24
  • 48