0

I am aware that according to the C standard one's not allowed to perform an unaligned memory read, since it may result in a SIGBUS.

Nevertheless, I've seen some machines where this is not an issue.

How do I know if it's safe to read from unaligned memory on my machine? More specifically, I am using Amazon Linux.

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 60
Stepping:              3
CPU MHz:               800.000
BogoMIPS:              7981.41
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7
  • 4
    If you are not caught stealing a car, is stealing a car allowed? – too honest for this site Feb 04 '16 at 18:17
  • 1
    I think, this sums it up quite well: https://www.kernel.org/doc/Documentation/unaligned-memory-access.txt – Ctx Feb 04 '16 at 18:19
  • It is never safe, just trust the standard (can you quote or provide a link to the statement you're referring to ? ) – Bludzee Feb 04 '16 at 18:25
  • 1
    This is not even a question of which machines support it - Linux has for some time patched it up on some platforms - so it's a question of CPU, operating system and operating system configuration. – marko Feb 04 '16 at 18:31
  • @marko, is there any way to know if my CPU, OS and OS config allow altogether unaligned reads? That's the question. – Mario Borges Feb 04 '16 at 21:24
  • Write a program that attempts them and see whether it crashes? This might be a viable proposition for feature detection in a build script. You can probably also do a probe at runtime if you catch the right signals. – marko Feb 05 '16 at 08:24

2 Answers2

5

The point is that in most cases, misaligned access is undefined behavior (if you claim to code portable and standard conformant C or C++ code).

Undefined behavior is always very bad, and it has the unpleasant property that sometimes it might seem to work (so having some program apparently work does not tell anything; it could break next time).

And in practice, on current machines accepting unaligned accesses (perhaps many x86_64 processors), such accesses are very slow because they make the CPU cache unhappy (by needing two memory reads at the hardware level). See also this.

So simply avoid unaligned access (and other forms of UB, including buffer overflows). Try to code for the standard, and follow common practice and wisdom. Enable all warnings in your compiler, and try to not get even a single one. See this link again for more recommendations.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    It's not *very slow* on modern x86 [since Sandy Bridge](http://www.agner.org/optimize/blog/read.php?i=627&v=t) https://stackoverflow.com/q/45128763/995714 – phuclv Jul 02 '18 at 02:04
3

Will it "work" in the environment you have described? "Yes", (with a performance penalty.)

Is it safe? If you cross a busy street blindfolded and make it safely to the other side, was that "safe"?

John Hascall
  • 9,176
  • 6
  • 48
  • 72