Live data from Hacker News

A bug story: data alignment on x86

pzemtsov.github.io

91–100 of 111 posts

Re: A bug story: data alignment on x86

#91

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

Again someone blaming the victim. I'm kind of sick of this. While true, your comment doesn't get at the root of the problem. The obvious fact here is that there is a mismatch between the C standard and how the users really use it. The less obvious fact/opinion/fallacy, is that it is not automatically the user's fault. The standard could be wrong. Sure, there are reasons why such and such behaviour ended up undefined.…

Undefined behavior is one of the most intelligent things the C designers did when designing the language.

It's a fact of life that not all syntactic forms will have meaning. What's sqrt(-1)? Trick question, There's no meaningful answer (in terms of real numbers alone)! Why should anyone specify if it crashes the program, returns 0, throws an exception, etc.? Who cares? garbage in, garbage out.

Another example, "the floor had a pretty day with his melted spaceship" that is a grammatically well formed sentence but what does it mean? Don't answer that!

Re: A bug story: data alignment on x86

#92
post #11

The correct solution for GCC is specifying 1-byte alignment for this particular array: #include #include typedef uint32_t __attribute__((__aligned__(1))) uint32_t_unaligned; uint64_t sum (const uint32_t_unaligned * p, size_t nwords) { uint64_t res = 0; size_t i; for (i = 0; i Probably works on clang too and IIRC the MS compiler provides similar functionality with different syntax. AFAIK there is no portable solution.…

Nah, correct solution is simply to use memcpy(), works on all compilers, all platforms, all versions, with SSE and with any flags specified:

  #include 
  #include 

  uint64_t sum (char *p, size_t nwords)
  {
      uint64_t res = 0;
      size_t i;
      for (i = 0; i 

Re: A bug story: data alignment on x86

#93
post #63
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…

I believe you are confusing undefined behavior and implementation defined behavior. Undefined behavior is illegal under all compilers, and all bets are off if you do it. Implementation defined behavior is always legal, but different compilers are allowed to do different things.

Undefined behavior is not illegal. The compiler can do anything with undefined behavior, including exactly what the author expected.

Re: A bug story: data alignment on x86

#94

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

Again someone blaming the victim. I'm kind of sick of this. While true, your comment doesn't get at the root of the problem. The obvious fact here is that there is a mismatch between the C standard and how the users really use it. The less obvious fact/opinion/fallacy, is that it is not automatically the user's fault. The standard could be wrong. Sure, there are reasons why such and such behaviour ended up undefined.…

There are no victims in engineering. Such phraseology should be saved for disciplines where emotion trumps reason, like politics.

Re: A bug story: data alignment on x86

#95

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

Again someone blaming the victim. I'm kind of sick of this. While true, your comment doesn't get at the root of the problem. The obvious fact here is that there is a mismatch between the C standard and how the users really use it. The less obvious fact/opinion/fallacy, is that it is not automatically the user's fault. The standard could be wrong. Sure, there are reasons why such and such behaviour ended up undefined.…

You are missing the point. The standard could be wrong, but it is still the standard. You still have an obligation to conform to it if you are writing C code. It is a prescriptive document, not a descriptive one. It can only be wrong to the extent that it can make poor decisions. Regardless of what it says it is authoritative.

Re: A bug story: data alignment on x86

#96
post #86

Earlier quoted context omitted.

The final element of the struct is a zero length array of elements of size N bytes. So that element isn't padding, it has size 0! It's pure hinting. I'm not sure why or how this works under the hood I'm afraid. I used it successfully to call a library with pretty strict alignment requirements (Intel Embree).

The zero length array still must be aligned correctly. You can create a pointer to it (e.g. by taking &something._alignment[..] to create a slice) and pointers must have correct alignment, so it follows that a zero length array has the same alignment requirements as a longer array. So padding must be inserted in your struct so that the address of the zero-length array is correctly aligned.

Hmm, I don't understand (sorry). The pointer to the internal array must be aligned. But how does the element size play into the padding. If we take these two examples?

   [repr(C)]
   struct StructA
   {
      pub foo: f32,
      _alignment: [SixteenBytes, 0]
   }

   [repr(C)]
   struct StructB
   {
      pub foo: f32,
      _alignment: [ThirtytwoBytes, 0]
   }
Are both just padded with 16-4 and 32-4 bytes respectively, so they are equivalent to making a padding like this in the first case?

   [repr(C)]
   struct StructAPadded
   {
      pub foo: f32,
      _padding : TwelveBytes;
   }

Re: A bug story: data alignment on x86

#97
post #63

Earlier quoted context omitted.

I believe you are confusing undefined behavior and implementation defined behavior. Undefined behavior is illegal under all compilers, and all bets are off if you do it. Implementation defined behavior is always legal, but different compilers are allowed to do different things.

Undefined behavior is not illegal. The compiler can do anything with undefined behavior, including exactly what the author expected.

It is illegal, for any reasonable definition of illegal. See my comment from earlier in the year: https://news.ycombinator.com/item?id=10840497

Re: A bug story: data alignment on x86

#98
post #40
post #11

The correct solution for GCC is specifying 1-byte alignment for this particular array: #include #include typedef uint32_t __attribute__((__aligned__(1))) uint32_t_unaligned; uint64_t sum (const uint32_t_unaligned * p, size_t nwords) { uint64_t res = 0; size_t i; for (i = 0; i Probably works on clang too and IIRC the MS compiler provides similar functionality with different syntax. AFAIK there is no portable solution.…

You also need the may_alias attribute to prevent other problems. Data written as int may be read as char, but going the other way is usually a standards violation. (an exception being if you had used char to implement a memcpy-like function, but in that case you should expect compiler bugs to bite you)

Interesting, but is this a real world problem or just a standard nobody follows? I'm under impression that lots of networking and storage code running in the wild casts back and forth between char arrays and other types without giving it a thought.

And yes, as for other casts, I'm well aware that they cause problems.

Re: A bug story: data alignment on x86

#99

Earlier quoted context omitted.

Again someone blaming the victim. I'm kind of sick of this. While true, your comment doesn't get at the root of the problem. The obvious fact here is that there is a mismatch between the C standard and how the users really use it. The less obvious fact/opinion/fallacy, is that it is not automatically the user's fault. The standard could be wrong. Sure, there are reasons why such and such behaviour ended up undefined.…

There are no victims in engineering. Such phraseology should be saved for disciplines where emotion trumps reason, like politics.

I disagree.

Engineering is full of needlessly awkward tools that end up being misused because of their useless warts. Every time that happens, the engineer that uses it is kind of a victim. And of course, there are the end users, who end up irradiated, spied upon, or robbed because of a technical failure allowed by needlessly unsafe tools.

(Big emphasis on "needlessly". Sometimes, the requirements are so stringent that only the unsafe tools do the job. Embedded environments, AAA games, or video encoders come to mind. Most of the time though, safer, less efficient tools are more than enough.)

Re: A bug story: data alignment on x86

#100
post #63
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…

I believe you are confusing undefined behavior and implementation defined behavior. Undefined behavior is illegal under all compilers, and all bets are off if you do it. Implementation defined behavior is always legal, but different compilers are allowed to do different things.

I'm not.

Undefined behavior is 'anything goes'. An implementation can choose a particular behavior that you can rely on for a particular case of UB, because, if the only rule is that 'anything goes', it doesn't violate that rule.

I'll admit that compilers don't generally do that - because specifying it could lead to fewer optimizations. But I did say "if", and there's no reason they couldn't do so in principle.

One could imagine a compiler with an extremely strict debug mode that traps on a number of situations that the standard deems undefined behavior via a segfault, in order to help people avoid relying on UB. Again - saying something like "casting misaligned pointers causes a segfault on [system]" would in no way violate a standard that says "casting misaligned pointers can do anything", because segfaulting falls under the umbrella of anything.

I think you're misinterpreting the fact that the results of undefined behavior can be ignored by a compiler for a requirement that it must be ignored by a compiler.

Post reply on HN