Live data from Hacker News

GCC always assumes aligned pointer accesses

trust-in-soft.com

21–30 of 93 posts

Re: GCC always assumes aligned pointer accesses

#21
post #8

No. [as in: this isn't about GCC.] The C standard requires that pointers generally be created from referencing a valid, existing object. A misaligned integer is not a valid "object", thus the compiler may assume that all pointers to ints are aligned (to 4 bytes.) https://en.cppreference.com/w/cpp/language/pointer Every value of pointer type is one of the following: - a pointer to an object or function (in which case…

I'm glad the OP posted this article to remind of some of the complexities of C (and C issues in C++) development. However, to coerce some of the bad examples OP used casting. This breaks the larger claim. A proper example of the issue would start with a bonafide int* word aligned and get to a non-aligned access without casting. Others mention packed v. non-packed structures ... this seems a more likely way to shoot yourself in the foot.

Re: GCC always assumes aligned pointer accesses

#22
post #17
post #9

Earlier quoted context omitted.

Irrelevant to the post, even without strict aliasing the compiler will assume pointers/objects are properly aligned.

Do you have an example where the compiler generates bad code that doesn’t involve misaligned aliases? Many programs rely on misaligned access, and features like pragma packed do too. I doubt they’ll be able to break all of that legacy code.

> Many programs rely on misaligned access, and features like pragma packed do too. I doubt they’ll be able to break all of that legacy code.

It's already broken. You're just not seeing it on x86. (Not sure how tolerant ARM is.)

I work in network software engineering, i.e. PowerPC used to be a common architecture. Those never accepted misaligned pointers (albeit you could of course trap the misalignment exception and emulate the access, or print a backtrace to identify the location.)

Really this is a problem caused by the "common case" (x86) being permissive in what it accepts, creating fallout further down the line if you ever need the code to run on something less permissive.

[Edit: actually, oops, it's not PowerPC; those are relatively permissive too. Pretty sure DEC Alpha and m68k are restrictive.]

Re: GCC always assumes aligned pointer accesses

#23
post #8

No. [as in: this isn't about GCC.] The C standard requires that pointers generally be created from referencing a valid, existing object. A misaligned integer is not a valid "object", thus the compiler may assume that all pointers to ints are aligned (to 4 bytes.) https://en.cppreference.com/w/cpp/language/pointer Every value of pointer type is one of the following: - a pointer to an object or function (in which case…

Why "no", you're agreeing with the conclusion

Sort of. He definitely talks about the fact that it is undefined behaviour to create a misaligned pointer:

> Strictly speaking, the function f invokes Undefined Behavior when it computes [the misaligned pointer]

But he thinks it is still a problem with GCC, in that GCC should not be allowed to take advantage of this particular UB. He explains his view much better in the bug report:

> GCC assumes that pointers must be aligned as part of its optimizations, even if the ISA does not force it (for instance, x86-64 without the vector instructions). The present feature wish as for an option to make it not make this assumption.

> Since the late 1990s, GCC has been adding optimizations based on undefined behavior, and “breaking” existing C programs that used to “work” by relying on the assumption that since they were compiled for architecture X, they would be fine. The reasonable developers have been kept happy by giving them options to preserve the old behavior. These options are -fno-strict-aliasing, -fwrapv, ... and I think there should be another one.

Re: GCC always assumes aligned pointer accesses

#24
About 30 years ago, I was porting an Ethernet driver to the MC88K, which also didn't allow misaligned accesses. Guess what happens when you fill a page-aligned buffer with an Ethernet packet, go past the 14-byte Ethernet header, and try to read the first 4-byte value in the IP header as a single word? You guessed it: SIGBUS. Every time. The same problem existed many other places, so I had to go find all of them. Eventually I implemented an exception handler that would emulate the access, and also log an error message. For months afterward, this turned up ever more obscure cases until there seemed to be none left.

Coming next: how modern programmers can't imagine a different word size or byte order. After that: different memory-ordering models. That one's really fun.

Re: GCC always assumes aligned pointer accesses

#25
Specifying a target architecture (ISA) when compiling does not change the programming language's semantics.

C is not a high-level assembly language, as pointed out in the article.

So just because you know that the target CPU supports e.g. unaligned accesses does not make them suddenly valid C.

Re: GCC always assumes aligned pointer accesses

#27
post #14

Earlier quoted context omitted.

Why "no", you're agreeing with the conclusion

"No, it's not GCC's fault / doing something weird." :) But, yes. Edited to clarify. FWIW this isn't a new problem either. If you wrote some C code in the 90ies using misaligned pointers, and then tried porting it to, say, a DEC Alpha, you'd get a SIGBUS in your face on first dereferencing such a pointer.

MC68k (anno 1979) didn't like misaligned memory access either and I have no reasons to believe that this started with Motorola. But yes, it's always fun watching a new generation falling into the old traps.

Re: GCC always assumes aligned pointer accesses

#28

About 30 years ago, I was porting an Ethernet driver to the MC88K, which also didn't allow misaligned accesses. Guess what happens when you fill a page-aligned buffer with an Ethernet packet, go past the 14-byte Ethernet header, and try to read the first 4-byte value in the IP header as a single word? You guessed it: SIGBUS. Every time. The same problem existed many other places, so I had to go find all of them. Even…

Mixed memory order as in, a memory write stores the data in an order like 5, 7, 6, 4 instead of 4, 5, 6, 7?

Re: GCC always assumes aligned pointer accesses

#29
post #15
post #12

Earlier quoted context omitted.

The compiler would know that the alignment is smaller than the type itself, which would disable the optimization mentioned in the post.

It literally cannot. The function in the linked article, that takes two pointers, must be compiled in isolation. If it needs to depend on alignment or overlapping, it needs to emit code to check it. And the standard does not require it to, nor do typical users want that. It's true that fancy tricks like LTO can make that kind of behavior visible to the optimizer, but the standard predates that kind of magic by severa…

That's not what I meant.

On an architecture where "long long" is 8 bytes, but only has a 4 byte alignment requirement, the compiler knows this, and knows that 2 pointers of type "long long * " may overlap. Therefore it would disable the optimization. (Except the pointers still aren't supposed to overlap, but...)

Re: GCC always assumes aligned pointer accesses

#30

Earlier quoted context omitted.

Why "no", you're agreeing with the conclusion

Sort of. He definitely talks about the fact that it is undefined behaviour to create a misaligned pointer: > Strictly speaking, the function f invokes Undefined Behavior when it computes [the misaligned pointer] But he thinks it is still a problem with GCC, in that GCC should not be allowed to take advantage of this particular UB. He explains his view much better in the bug report: > GCC assumes that pointers must be…

The problem with disabling this optimisation is that it will produce garbage code for basically every architecture. Code which does unaligned accesses are noticeably slow compared to aligned accesses -- this is why there are separate instructions and intrinsics for aligned and unaligned addresses on most architectures. That way you don't pay the penalty of unaligned accesses all the time. But if you try to use the aligned instructions on unaligned pointers you will get all sorts of fun errors.

And note that this slowdown would have to apply to every pointer operation in your program because GCC can't know whether a pointer is aligned at compile-time. I'm sure many more people would complain about significant performance slowdowns in a GCC update than about unaligned memory accesses being something you need to do with great care in C.

Post reply on HN