Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

121–130 of 503 posts

Re: Undefined behavior in C is a reading error

#121
post #49

Earlier quoted context omitted.

So if it is behavior that is not defined by the C standard, would that not make it undefined behavior?

While technically correct, “undefined behavior” in terms of C and C++ refer to what the standard calls out explicitly as undefined, and not a simple “it’s not referenced, therefore it’s undefined.” For example, signed(?) integer overflow is explicitly undefined by the standard, but as @formally_proven said, just because write(2) isn’t mentioned doesn’t mean usage of it is undefined.

Actually, that's exactly what it means:

> If a "shall" or "shall not" requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words "undefined behavior" or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe "behavior that is undefined".

write() is a function, and a call to it behaves like a function call, but the C standard says nothing about what that function does. You could have a function named "write" that writes 0xdeadbeef over the caller's stack frame. Of course if "write" is the function defined by POSIX, then POSIX defines how it behaves.

Re: Undefined behavior in C is a reading error

#122

First: I do dislike how hard it is to avoid some UB / how impractical some of the rules are. But I also think a lot of discussions of this topic caricaturize compiler writers to a ridiculous degree. Almost describing them to write optimization passes looking for UB so they can over-optimize something, while cackling loudly in glee about all the programs they can break. The set of people doing so overlaps with the set…

The caricatures are somewhat accurate though, optimizations that look at UB adversarially are never anywhere close to justified.

> The set of people doing so overlaps with the set of people complaining that the compiler doesn't optimize their code sufficiently to a significant degree.

There's no contradiction here, and the overlap is generally just "people who care". The optimizations that are not safe shouldn't exist, and the optimizations that are safe should be good.

> nearly all of the time are things the code author would agree with if they thought long and hard

I highly doubt this is the case for even one situation.

Re: Undefined behavior in C is a reading error

#123
post #112

Earlier quoted context omitted.

> Note that if the standard had not declared "n But also note that a lot of existing code doing bitshift-and-index inside a hot loop that never went out of bounds would now get slower if it started having to run bounds checks it had previously elided in an optimization pass. Let's not pretend that "it results in some implementation-specific value, or maybe traps" is a clear win with no downsides that Standards Author…

It isn't clear to me precisely what example you have in mind. If you are saying that deleting array bounds checks might have performance benefits that outweigh the security concerns, then I disagree. If you are saying that the compiler would have to insert bounds checks, I don't see how you arrive at that. I have seen claims that gratuitous UB is important for enabling meaningful optimizations, but in every such case…

> If you are saying that deleting array bounds checks might have performance benefits that outweigh the security concerns, then I disagree.

I'm saying that there is existing code in this world in which some variation on

       /* insanely hot loop where ARRAYSIZE > 32 */
       while(true) {
           ...
           int x = 1 
exists that's currently compiling down to just "a[index] = 1 I'm saying that the authors and their customers are unlikely to be excited when your new compiler release stops assuming that index is The point, broadly: People care a lot about performance. These UB discussions in which people blithely assert that compilers "should" do XYZ conservative assumption while eliding any mention of the real-world performance impact the changes they want would have on existing code are, frankly, masturbatory.

Compiler engineers have to care when PostgreSQL and a dozen other critical programs get 4x slower because they stopped assuming that "1 32, or that loop bounds won't overflow. Like all software engineering, decision making here has to be driven by balancing tradeoffs, not by insisting that one treatment of the spec is obviously "the best approach" while ignoring any inconvenient consequences that change would have vs the status quo.

Re: Undefined behavior in C is a reading error

#124
post #112

Earlier quoted context omitted.

> Note that if the standard had not declared "n But also note that a lot of existing code doing bitshift-and-index inside a hot loop that never went out of bounds would now get slower if it started having to run bounds checks it had previously elided in an optimization pass. Let's not pretend that "it results in some implementation-specific value, or maybe traps" is a clear win with no downsides that Standards Author…

It isn't clear to me precisely what example you have in mind. If you are saying that deleting array bounds checks might have performance benefits that outweigh the security concerns, then I disagree. If you are saying that the compiler would have to insert bounds checks, I don't see how you arrive at that. I have seen claims that gratuitous UB is important for enabling meaningful optimizations, but in every such case…

[deleted]

Re: Undefined behavior in C is a reading error

#125
post #112

Earlier quoted context omitted.

> Note that if the standard had not declared "n But also note that a lot of existing code doing bitshift-and-index inside a hot loop that never went out of bounds would now get slower if it started having to run bounds checks it had previously elided in an optimization pass. Let's not pretend that "it results in some implementation-specific value, or maybe traps" is a clear win with no downsides that Standards Author…

It isn't clear to me precisely what example you have in mind. If you are saying that deleting array bounds checks might have performance benefits that outweigh the security concerns, then I disagree. If you are saying that the compiler would have to insert bounds checks, I don't see how you arrive at that. I have seen claims that gratuitous UB is important for enabling meaningful optimizations, but in every such case…

There are a half-dozen examples on this very thread and in linked bug reports, with detailed explanations by professional compiler writers.

If you think they don’t hold up to scrutiny, then you should get to work implementing these things, because you are likely a better compiler writer than most others in the world, including Christian Lattner of llvm fame, who provides many examples here.

https://blog.llvm.org/2011/05/what-every-c-programmer-should...

Re: Undefined behavior in C is a reading error

#126
post #3

If C is just a portable assembler then what if the assembly itself has undefined behaviour. :)

This exists, but the effect of undefined behavior in CPU architectures is a little bit more forgiving than the interpretation of UB in C to mean "literally the entire program has no meaning". Instead, usually the program will execute correctly up to the invalid instruction, and then something happens, and then the CPU will continue executing from that state. It's actually fairly difficult to build an instruction with…

There actually is a fair amount of truly undefined behavior for CPUs, but it's always at system/kernel mode rather than userspace for security reasons. You can search an ARM ISA for "UNPREDICTABLE" to see examples.

Re: Undefined behavior in C is a reading error

#127
post #95
post #82

Earlier quoted context omitted.

Unspecified result means the compiler must think about what could happen in case I made an error. UB means the compiler will trust me and concentrate on generate the fastest code ever. C is for clever programmers; if you don't want to be clever, you are free to use Go or something like that.

It's not so much about cleverness, but knowledge and vigilance. You first have to be aware of all the footguns, and then be careful not to let any of them slip through...

> You first have to be aware of all the footguns,

Knowing your tools is part of being a professional. C is not for amateurs.

Re: Undefined behavior in C is a reading error

#128
post #94

Earlier quoted context omitted.

for (int i=param; i does not have a guaranteed loop count with the current rules. The loop body will execute 16 times if param <= INT_MAX-16, but if the expression "param + 16" can overflow, the behavior is undefined. (I'm assuming param is of type int.)

> does not have a guaranteed loop count with the current rules. The loop body will execute 16 times if param And the standard permits us (among other responses) to ignore undefined behaviour, so it does have a guaranteed loop count under a reading of the standard which the standard specifically and explicitly allows.

Either the limit on param is guaranteed in some way by the rest of the program, or it is not. If it is, then the loop count is guaranteed in both cases. If it is not, the loop count is not guaranteed in either case.

Re: Undefined behavior in C is a reading error

#129
This was posted by a user with a name closely matching the domain (perhaps the original author?) 16 hours prior, and flagged: https://news.ycombinator.com/item?id=27215697

When I stumbled across it last night, I couldn't understand why that would be. The content seemed good enough for readers on here, and this one's placement on the 2nd page of HN seems to confirm that. What's going on?

Re: Undefined behavior in C is a reading error

#130
post #36

I don't see any utility in inventing a new reading of the standard. Getting everyone to agree on a new interpretation of a sentence can't possibly be easier than getting everyone to agree on a more clearly worded sentence. The actual thing you'd have to convince everyone of (the utility of the new consensus) and the people you'd have to convince (compiler writers, documentation authors) are the same in both cases.

The difference is that, once decided and written, no party (both old and new) can’t chime in with a new interpretation.

> The difference is that, once decided and written, no party (both old and new) can’t chime in with a new interpretation.

That double negative ("no party … can't") was accidental, right?

Post reply on HN