Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

291–300 of 503 posts

Re: Undefined behavior in C is a reading error

#291

Specifying that anything can be done in the presence of UB is a poor specification. The word "specify" is pretty much the opposite of "anything." Perhaps compilers should delete all scopes with UB: much more UB would be purged from code as a result (programmers would be forced to enable compiler errors on UB).

Compilers generally do delete all scopes where they can detect that UB is certain (assuming that they can't happen and thus those sections are unreachable code) - but they can't detect and delete all scopes where UB is possible given certain input data, that would contradict the halting theorem and all that.

Re: Undefined behavior in C is a reading error

#292

Earlier quoted context omitted.

For me, the canonical UB example is a buffer overflow. No matter how you define UB, in practice a buffer overflow can result in for example, a system crash or - given appropriate very specific input data - encrypting all the files on your hard drive for a ransom. Requiring compilers to restrict UB to something similar to unspecified behavior (where the behavior is not specified by the standard, but a C implementation…

The trouble here is porting the maximalist disaster of one scenario to another scenario simply because the same phrase is used to describe them. Because a buffer overflow may lead to arbitrary control flow escape via ROP or other hijacking of the instruction pointer, it does not follow that e.g. signed overflow is similarly dangerous. Signed overflow, if not guarded against, may enable buffer overflow, but the deeper…

Yes, now if the proposal would be not to redefine the semantics of UB (as the post to which I replied suggested) but rather about specifying that buffer overflows are UB1 and integer overflows are UB2, and UB2 means something different from UB1 (perhaps identical to implementation-specified behavior, perhaps something different), then that could be reasonable.

Re: Undefined behavior in C is a reading error

#293
post #194

Earlier quoted context omitted.

To do UB "optimizations", the compiler first needs to figure out that there is an UB it can "optimize" anyway. At this point instead of "optimizing" it could, and in my humble opinion absolutely should, blow up the compilation by generating an UB error, so people can fix their stuff. What about backwards compatibility in regards to a new compiler version deciding to issue errors on UB now? You don't have any guarante…

> To do UB "optimizations", the compiler first needs to figure out that there is an UB it can "optimize" anyway. The compiler assumes UB will never happen and it makes transformations that will be valid if there happens to be no UB. This doesn't require any explicit detection of UB, and in some cases UB or not is simply undecidable at compile time (as in no compiler could detect it without incorrect results). Without…

Yes, some UB are not decidable at compile time, but a lot could be easily speced to have a defined behavior at runtime, such as overflows.

The main reason to not spec these things is because people would be arguing "this makes compiled code on my esoteric 9-bit 1-complement chip slower" or "there was this chip in the 70s that did things differently" or "but a short int on Cray was 64-bit". Great, so now the spec has avoidable unnecessary undefined behavior all over the place, and the code other people wrote still does not run correctly on your 9-bit chip. Brought to you by the same people who decided "NULL is not necessarily (void*)0", and who define those integer types everybody uses (instead of stdint) with an "at least this big".

Yes, a lot of that is legacy stuff and was added to accommodate and model things that already existed (the wrong way to go about it, IMO, but hindsight is 20/20), but that's my argument: fix this stuff once and for all and for good in an upcoming spec iteration.

>Without these assumptions the resulting compiled code would be much slower

In some cases, this is true (for different levels of "much slower"), but the trade off here is still "running code that works, but a little slower" vs "running code that does not work and will launch a nuclear strike at Switzerland by accident, but really fast".

In a lot of cases, it will not be slower, or at least not much slower.

>I think your irritation is just based on a misunderstanding of the situation.

Frankly, not really. I started writing my first C (and C++) in the early 90s, and I think I do understand the situation pretty well by now. But I should have been more precise in my initial ranting comment, I give you that.

>They're not trying to screw anyone over.

I didn't say that they are.

Re: Undefined behavior in C is a reading error

#294
post #264
post #245

Earlier quoted context omitted.

> and the commtitee I'd argue that for a document like the C standard, if there's a well-known intended meaning, that is the meaning of the document - any other interpretation is purely academic.

These are all interpretations. Your trying to special privilege one interpretation by calling it the intended meaning when really it’s what I’d call an authoritative interpretation. The accepted interpretation by an authority. That doesn’t necessarily make it the actual intended meaning though.

It sounds like you're arguing that the authors' interpretation isn't an authoritative interpretation.

Is this what you meant?

Re: Undefined behavior in C is a reading error

#295
post #139

Earlier quoted context omitted.

> For example, if signed integer overflow yielded an unspecified result rather than causing undefined behavior, I wonder if any implementations would be adversely affected. I suspect so - makes it harder to reason about loop counts because the compiler can't necessarily guarantee that an incremented loop counter won't become negative and thus the loop needs to iterate more. E.g. something like for (int i=param; i Tha…

I don't know if there exists a C compiler that leverages this feature but there are ISAs (for instance MIPS) that can trap on signed overflow. The fact that it's UB in C means that you can tell the compiler to generate these exception-generating instructions, which could make some overflow bugs easier to track down without any performance implications. And your compiler would still be 100% compliant with the standard…

GCC is optimised for performing well on benchmarks at the expense of anything else. Vendor compilers for those architectures traditionally had more programmer-friendly features like trapping instead of creating an exploitable security vulnerability.

Re: Undefined behavior in C is a reading error

#296
post #287

Earlier quoted context omitted.

For me, the canonical UB example is a buffer overflow. No matter how you define UB, in practice a buffer overflow can result in for example, a system crash or - given appropriate very specific input data - encrypting all the files on your hard drive for a ransom. Requiring compilers to restrict UB to something similar to unspecified behavior (where the behavior is not specified by the standard, but a C implementation…

It goes further than that. The debates around UB a more about whether the compiler can assume that there are no buffer overflows and perform optimizations based on that. For example, if you have a local variable `char buffer[16]`, and there is an access `buffer[i]`, should the compiler be allowed to derive that 0 = 16, why shouldn't it? But some argue that the compiler shouldn't, exactly because such automated formal…

The result is a perpetually unstable situation fostering inevitable errors when the programmer is surprised by the compiler. There's no remedy except to move away from C to more tightly specified languages.

Re: Undefined behavior in C is a reading error

#297
post #31

The author suggests that the text following the definition of "undefined behavior", listing the permitted or possible range of undefined behavior, should be read to restrict the consequences. But the first possibility listed is "ignoring the situation completely with unpredictable results". Surely that covers any possible consequences. The author also says: > Returning a pointer to indeterminate value data, surely a…

IMO, implementation defined is worse. It is still a time bomb but now it is a time bomb that you cannot use compiler errors to prevent automatically.

How so? The implementation can, and perhaps should, define that it errors. Whatever behaviour you're worried about a compiler doing for implementation-defined behaviour, it could do exactly the same thing if the behaviour was undefined.

Re: Undefined behavior in C is a reading error

#298

Earlier quoted context omitted.

I would note that the article is explicitly contesting the definition of UB that you are giving here (though you are absolutely right that this is the de facto definition used by all major compilers, and the commtitee). Basically the article is arguing that UB should be similar to Unspecified behavior - behavior that the implementation leaves up to the hardware and/or OS. I'm not sure where I fall to this issue, thou…

For me, the canonical UB example is a buffer overflow. No matter how you define UB, in practice a buffer overflow can result in for example, a system crash or - given appropriate very specific input data - encrypting all the files on your hard drive for a ransom. Requiring compilers to restrict UB to something similar to unspecified behavior (where the behavior is not specified by the standard, but a C implementation…

> given appropriate very specific input data

That's the operative words there. Compilers are not required to ensure that, in sufficiently perverse circumstances, undefined behaviour never results in demons flying out of you nose. They are, however, required to not actively put said demons there themselves, because that's part of what distinguishes a programming language implementation from a piece of malware masquerading as a programming language implementation.

Re: Undefined behavior in C is a reading error

#299
post #279

Earlier quoted context omitted.

I would note that the article is explicitly contesting the definition of UB that you are giving here (though you are absolutely right that this is the de facto definition used by all major compilers, and the commtitee). Basically the article is arguing that UB should be similar to Unspecified behavior - behavior that the implementation leaves up to the hardware and/or OS. I'm not sure where I fall to this issue, thou…

> In particular, nothing in the wording of the standard expliclty says that an implementation is expected to assume UB doesn't happen, or that a standard-conforming program can't have UB. An implementation isn't expected to assume that UB doesn't occur, but it is allowed to assume that. With regard to programs, the C standard has two different notions of conformance (cf. chapter 4 Conformance). There are strictly con…

I despair at writing C code where the compiler won't silently surprise me. How are we supposed to learn all these subtle rules and intuit when to apply them without making any mistakes?

Re: Undefined behavior in C is a reading error

#300
post #82
post #31

The author suggests that the text following the definition of "undefined behavior", listing the permitted or possible range of undefined behavior, should be read to restrict the consequences. But the first possibility listed is "ignoring the situation completely with unpredictable results". Surely that covers any possible consequences. The author also says: > Returning a pointer to indeterminate value data, surely a…

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.

Expecting programmers to evaluate their own cleverness does not work. Every nontrivial C program has undefined behaviour, making it a security flaw waiting to happen - I've been in these kind of debates where a C advocate will claim that program X is correct, and literally every time it turns out that program X has undefined behaviour somewhere.
Post reply on HN