Live data from Hacker News

A bug story: data alignment on x86

pzemtsov.github.io

51–60 of 111 posts

Re: A bug story: data alignment on x86

#51
post #38

Again someone who relies on undefined behavior. Casting pointer of wrong alignement is not a platform specific behavior, it's an undefined behavior. Relying on it is an error. The author did not know "What Every C Programmer Should Know About Undefined Behavior": http://blog.llvm.org/2011/05/what-every-c-programmer-should-... Another good link about that: http://blog.regehr.org/archives/213

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

If.

(famous reply from Sparta, Laconia, to Philip II of Macedon)

Re: A bug story: data alignment on x86

#52
post #38

Again someone who relies on undefined behavior. Casting pointer of wrong alignement is not a platform specific behavior, it's an undefined behavior. Relying on it is an error. The author did not know "What Every C Programmer Should Know About Undefined Behavior": http://blog.llvm.org/2011/05/what-every-c-programmer-should-... Another good link about that: http://blog.regehr.org/archives/213

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

The thing is, many compilers just assume that undefined behaviour won't happen, without defining any particular behaviour. And testing for something like pointer alignment on architectures that silently allow pointer misalignment is really, really expensive.

That said, you can use -fsanitize=undefined to verify correctness of a program (as far specification is concerned). Just be prepared for it being a bit slow.

Re: A bug story: data alignment on x86

#53
post #38

Earlier quoted context omitted.

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

> If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. This is a great way to make your programs "fun" to port to new platforms with new compilers in terrifyingly subtle ways. I prefer not to recommend this approach to solving specific cases of undefined behavior, although if you happen to disable strict aliasing (with e…

You can also defensively add a quick test to your program's startup code and unit tests. Startup will take a tiny bit longer, but those porting your code will be thankful if they hit the problem, double so if you manage to emit a useful diagnostic.

Re: A bug story: data alignment on x86

#54
post #38

Earlier quoted context omitted.

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

The thing is, many compilers just assume that undefined behaviour won't happen, without defining any particular behaviour. And testing for something like pointer alignment on architectures that silently allow pointer misalignment is really, really expensive. That said, you can use -fsanitize=undefined to verify correctness of a program (as far specification is concerned). Just be prepared for it being a bit slow.

It's not possible to determine all possible undefined behavior in a C program. -fsanitize=undefined is best-effort.

Re: A bug story: data alignment on x86

#55
post #38

Again someone who relies on undefined behavior. Casting pointer of wrong alignement is not a platform specific behavior, it's an undefined behavior. Relying on it is an error. The author did not know "What Every C Programmer Should Know About Undefined Behavior": http://blog.llvm.org/2011/05/what-every-c-programmer-should-... Another good link about that: http://blog.regehr.org/archives/213

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

Technically, if a compiler specifies how it handles undefined behavior (as opposed to implementation-defined behavior, which it must define), it stops being a C compiler :-)

I also think it is fairly unlikely that any C compiler will say anything about how it handles undefined behaviour because it would mean it has to generate awfully inefficient code. For example, a compiler could not optimize away most pointer dereferencing code if it promised that dereferencing odd addressses segfaults.

Yes, such checks might add at most a few percent to a normal program's running time, but add in all the other corner cases (int overflow, boundary checks, etc.) that also dat a few percent, amd before you know it your program runs at half the speed it could run at. If you find that acceptable, you shouldn't be writing C in the 21st century.

Re: A bug story: data alignment on x86

#56
post #55
post #38

Earlier quoted context omitted.

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

Technically, if a compiler specifies how it handles undefined behavior (as opposed to implementation-defined behavior, which it must define), it stops being a C compiler :-) I also think it is fairly unlikely that any C compiler will say anything about how it handles undefined behaviour because it would mean it has to generate awfully inefficient code. For example, a compiler could not optimize away most pointer dere…

The standard explicitly permits documented behaviour, even though it doesn't have to, because "undefined" covers that option, along with anything else you care to imagine: http://port70.net/~nsz/c/c11/n1570.html#3.4.3

Re: A bug story: data alignment on x86

#57
post #3

Well, that's pretty horrendous. Note that the naive code which just casts the input to uint16_t would work fine. I can't help but wonder if the solution to this might have been better expressed as naive implementation + platform-specific assembly implementation. After all, if you have to understand the underlying instructions executed in order to fix the problem, why not stop trying to make the compiler emit the "rig…

> if you have to understand the underlying instructions executed in order to fix the problem

You don't. You can simply write the code without casting pointers. Sticking to char* will give you straightforward, working, annoying-looking code.

C is surprisingly poor-suited for doing input and output with data structures.

Re: A bug story: data alignment on x86

#58

Earlier quoted context omitted.

Not sure if this is what you are asking: Last time I tried alignment in Rust I worked around the lack of explicit alignment support by adding a zero length array of the correct size to the end of the struct. Not sure if alignment support from proper attributes has landed yet. [repr(C)] struct Something { pub foo: f32, pub _alignment: [EightBytes, 0] } where "EightBytes" is a data type of size 8, to align the whole st…

Structs already insert padding to give them alignment: struct One { foo: u8, } struct Two { bar: u16, } struct Three { foo: u8, bar: u16, } struct Four { foo: u16, bar: u16, } fn main() { assert_eq!(1, std::mem::size_of:: ()); assert_eq!(2, std::mem::size_of:: ()); assert_eq!(4, std::mem::size_of:: ()); assert_eq!(4, std::mem::size_of:: ()); }

Well given that Rust leaves struct layout undefined unless #[repr(C)] is specified, std::mem::size_of:: is actually not guaranteed to be 4.

Re: A bug story: data alignment on x86

#59
post #39

Earlier quoted context omitted.

The correct and portable solution is to not use uint32_t, but to use uint8_t, and construct the integers manually.

Well, portable except for `uint8_t` not being guaranteed to exist. =)

Which is a feature! If you use `char` instead of `uint8_t` your program would still compile on a system that doesn't have `uint8_t`, but it is likely to do something entirely unexpected. At least when you use `uint8_t` you are warned at compile-time that your program is broken.

Re: A bug story: data alignment on x86

#60
post #55
post #38

Earlier quoted context omitted.

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently. Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blo…

Technically, if a compiler specifies how it handles undefined behavior (as opposed to implementation-defined behavior, which it must define), it stops being a C compiler :-) I also think it is fairly unlikely that any C compiler will say anything about how it handles undefined behaviour because it would mean it has to generate awfully inefficient code. For example, a compiler could not optimize away most pointer dere…

[deleted]
Post reply on HN