10
votes

According to the Wikipedia page Segmentation fault, a bus error can be caused by unaligned memory access. The article gives an example about how to trigger a bus error. In the example, we have to enable alignment checking to see the bus error. What if we disable such alignment checking?

The program seems to work properly. I have a program access unaligned memory frequently, and it is used by quite a few people, but no one reports bus errors or other weird results to me. If we disable alignment checking, what is the side effect of unaligned memory?

Platforms: I am working on x86/x86-64. I also tried my program by compiling it with "gcc -arch ppc" on a Mac and it works properly.

3
What is the platform you are working on??Frank Bollack
Pavel Minaev largely answers my question. I am working on x86/x86_64. I tried my program by compiling it with "gcc -arch ppc" on Mac and it works properly.user172818
Note that unaligned memory access (actually, even just pointer assignment) is undefined behaviour according to the C standard - so a compliant compiler is allowed to do anything if you do it (though not all compilers will take that liberty).sleske
Related: Violating alignof(T) is undefined behaviour and can cause real-world problems even on x86, for example when auto-vectorizing the compiler may assume that a 16-byte alignment boundary is some whole number of shorts away : Why does unaligned access to mmap'ed memory sometimes segfault on AMD64?Peter Cordes

3 Answers

14
votes
  1. It may be significantly slower to access unaligned memory (as in, several times slower).

  2. Not all platforms even support unaligned access - x86 and x64 do, but ia64 (Itanium) does not, for example.

  3. A compiler can emulate unaligned access (VC++ does that for pointers declared as __unaligned on ia64, for example) - by inserting additional checks to detect the unaligned case, and loading/storing parts of the object that straddle the alignment boundary separately. That is even slower than unaligned access on platforms which natively support it, however.

6
votes

It very much depends on the chip architecture. x86 and POWER are very forgiving, Sparc, Itanium and VAX throw different exceptions.

2
votes

Consider the following example I have just tested on ARM9:

//Addresses       0     1     2    3     4     5     6     7      8    9
U8 u8Temp[10] = {0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00};

U32 u32Var;

u32Var = *((U32*)(u16Temp+1));  // Let's read four bytes starting from 0x22

// You would expect that here u32Var will have a value of 0x55443322 (assuming we have little endian)
// But in reallity u32Var will be 0x11443322!
// This is because we are accessing address which %4 is not 0.