I'm going to rant right back. You're the one who's misinformed. (And I'm going to attach a disingenuous smiley.)
There's a good reason that I and many other people continue to complain about compilers' adventurous interpretation of the standards. You persist in blaming programmers who clearly indicate the intent of their programs for compiler writers ignoring that intent in search of faster benchmarks, using bits undefined behavior intended to account for platform differences to actually distort programs.
> It's spec'd that way
Yes. So what? The spec is harmful. It is a bad spec. It doesn't reflect C as actually written.
> it's documented that way
Yes. So what? Not every documented behavior is good.
> there's a good reason why it is that way
Absolutely not. memset, memcpy, look and act like normal functions and only have this weird undefined behavior by special dint of the relevant standards. That's very surprising and leads to real bugs.
Other undefined behavior is similar. There's no reason on modern systems to make arbitrary pointer arithmetic undefined. There is no reason to make signed integer overflow undefined either --- unspecified, maybe, but certainly not undefined.
(Except, that is, for loop optimization, but that's a bullshit and lame excuse that compiler writers use to avoid having to do real bounds inference.)
> memset() should not try to guess what you mean in an error condition.
That's not a fucking error condition, and you know it. memset(0,0,0) to any honest person means "do nothing to zero bytes", not "make my program do whatever compiler authors want". memset and memcpy of NULLs can occur in normal program logic, sometimes surprisingly, and there is absolutely no legitimate reason for treating these occurrences as undefined behavior.
> let's redefine floating point so that 0.1+0.2==0.3.
You know damn well that there's a good reason IEEE754 floating point is inexact when expressed in decimal. That's not the case with the undefined behavior that compiler writers currently exploit.
> How about shifting a uint32_t by 32 bits?
Specify that it returns zero or the original value, but don't allow the compiler to consider it unreachable, trap, or do other random shit.
> Alright, I'm sick of this shit on Hacker News.
The tone of your post and others like it is intolerable. It is precisely victim blaming. Compiler writers aren't taking advantage of undefined behavior to account for DSPs: they're doing it to win benchmarks that don't matter in the real world. (The memset issue is particularly egregious.) This process harms users and developers by introducing bugs.
You're the one who's badly-informed, not me. Practically every program, even extremely well-tested ones like SQLite, contain undefined behavior. See http://blog.regehr.org/archives/1292. (Read the whole blog, actually.)
Now, what good does it do say that almost every C program on earth is actually at fault? That's just giving compiler writers license to do whatever they'd like. When even very careful programmers trip over obscure parts of the standard, it's the standard that must change.
Alright, I'll bite, because you make some good points. Having reconsidered, I'm not entirely sure I'm in the right here anyway.
> using bits undefined behavior intended to account for platform differences to actually distort programs.
You can't really distort a program that doesn't have a valid interpretation to begin with.
> Yes. So what? The spec is harmful. It is a bad spec. It doesn't reflect C as actually written.
The spec is written to be cross-platform, and C as it is actually written typically is not cross-platform. Which is fine, actually, since generally programs don't need to run on both bare metal on a microcontroller and on a supercomputer. Portable between similar-purpose processors is enough.
The spec probably shouldn't reflect C as it is written anyway, rather C should be written to reflect the spec....
> memset, memcpy, look and act like normal functions and only have this weird undefined behavior by special dint of the relevant standards.
Can't any function do anything if that's part of its contract? We can write a div(x,y) function that deletes System32 if you divide by 0, and just say that division by zero is undefined.
> There's no reason on modern systems to make arbitrary pointer arithmetic undefined.
Fair enough.
> There is no reason to make signed integer overflow undefined either
That one is actually rather important for performance though.
> (Except, that is, for loop optimization, but that's a bullshit and lame excuse that compiler writers use to avoid having to do real bounds inference.)
> memset(0,0,0) to any honest person means "do nothing to zero bytes"
Yes, we really need more honest people to write compilers.
I think appealing to “honest person” or “what most people would expect” etc is a weak argument. Sometimes the correct behavior isn't what people expect, and sometimes there is no correct behavior.
> memset and memcpy of NULLs can occur in normal program logic, sometimes surprisingly
I believe that'd be an error condition. Check for NULL before you memcpy to NULL. Frankly though the circumstances where you memcpy or memset something that even could be NULL is pretty rare. Usually it's something recently allocated (stack or heap).
> Specify that it returns zero or the original value, but don't allow the compiler to consider it unreachable, trap, or do other random shit.
That would be reasonable. Perhaps some things, such as shifting, could be implementation-defined. I did, I think, ignore the idea that some undefined things could just be unspecified in my original rant.
> That's not the case with the undefined behavior that compiler writers currently exploit.
Perhaps not in all cases, but in many cases there is a good reason for undefined behavior being undefined: it doesn't make sense in the context of the C abstract machine. Derefencing a NULL pointer, for example, may be perfectly valid on an embedded CPU with no memory protection. C isn't defined to “how this should work on my x86_64 Macbook Pro,” it's defined to “how this should work—or not work—on the C abstract machine.” If on some particular implementation of the C machine that means “delete this basic block at compile time” then so be it. You're not entitled to tell compiler writers how to interpret undefined behavior.
> The tone of your post and others like it is intolerable. It is precisely victim blaming.
Yes, the evil evil compiler writers are conspiring to look good in benchmarks and poor programmers are the victims. Victims!
You are so damn ungrateful it hurts. You're not a fucking victim.
> Practically every program, even extremely well-tested ones like SQLite, contain undefined behavior.
I keep pondering whether this is a problem or not. If the compiler can't prove that it's undefined at compile time, then it just depends on the processor and the only problem is that your program is not portable to obscure special-purpose architectures. On the other hand, the fact that any non-trivial program needs to invoke undefined behavior is pretty damning evidence that the spec is insufficient.
I think, ultimately, I concede that the C standard is flawed. But please get over your fucking entitlement complex about how compiler writers take more liberties with UB than you would.
There's a good reason that I and many other people continue to complain about compilers' adventurous interpretation of the standards. You persist in blaming programmers who clearly indicate the intent of their programs for compiler writers ignoring that intent in search of faster benchmarks, using bits undefined behavior intended to account for platform differences to actually distort programs.
> It's spec'd that way
Yes. So what? The spec is harmful. It is a bad spec. It doesn't reflect C as actually written.
> it's documented that way
Yes. So what? Not every documented behavior is good.
> there's a good reason why it is that way
Absolutely not. memset, memcpy, look and act like normal functions and only have this weird undefined behavior by special dint of the relevant standards. That's very surprising and leads to real bugs.
Other undefined behavior is similar. There's no reason on modern systems to make arbitrary pointer arithmetic undefined. There is no reason to make signed integer overflow undefined either --- unspecified, maybe, but certainly not undefined.
(Except, that is, for loop optimization, but that's a bullshit and lame excuse that compiler writers use to avoid having to do real bounds inference.)
> memset() should not try to guess what you mean in an error condition.
That's not a fucking error condition, and you know it. memset(0,0,0) to any honest person means "do nothing to zero bytes", not "make my program do whatever compiler authors want". memset and memcpy of NULLs can occur in normal program logic, sometimes surprisingly, and there is absolutely no legitimate reason for treating these occurrences as undefined behavior.
> let's redefine floating point so that 0.1+0.2==0.3.
You know damn well that there's a good reason IEEE754 floating point is inexact when expressed in decimal. That's not the case with the undefined behavior that compiler writers currently exploit.
> How about shifting a uint32_t by 32 bits?
Specify that it returns zero or the original value, but don't allow the compiler to consider it unreachable, trap, or do other random shit.
> Alright, I'm sick of this shit on Hacker News.
The tone of your post and others like it is intolerable. It is precisely victim blaming. Compiler writers aren't taking advantage of undefined behavior to account for DSPs: they're doing it to win benchmarks that don't matter in the real world. (The memset issue is particularly egregious.) This process harms users and developers by introducing bugs.
You're the one who's badly-informed, not me. Practically every program, even extremely well-tested ones like SQLite, contain undefined behavior. See http://blog.regehr.org/archives/1292. (Read the whole blog, actually.)
Now, what good does it do say that almost every C program on earth is actually at fault? That's just giving compiler writers license to do whatever they'd like. When even very careful programmers trip over obscure parts of the standard, it's the standard that must change.