Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

471–480 of 503 posts

Re: Undefined behavior in C is a reading error

#471
post #464

Earlier quoted context omitted.

> let me quote where the standard says so: Wouldn't this hinge on what precisely "entire program" means? A definition for write(2) may not appear in the source code you wrote, but if "entire program" includes e.g., libraries dynamically linked in then it's quite feasible for the end result to be fully defined. For example, 5.2.2 Paragraph 2 starts with (emphasis added): > In the set of translation units and libraries…

Sure, but in the situation we were talking about, the user never wrote a definition for write(), and the user did not specify any library to include that provided a definition of write(). From the standard's perspective, that means there is no definition for it in the entire program. Keep in mind that the standard's perspective is somewhat different from how things work in practice. We know that on Unix-like systems,…

> and the user did not specify any library to include that provided a definition of write()

Ah. I had assumed that that was implicit in "using write(2)", but seems that was a bad assumption.

> there is also the concept of libraries, somewhat different from how the standard describes it

In what way?

You make an interesting point with the example. It's not something I had considered before. Would weak linkage (or a similar mechanism that allows for a provide-unless-the-user-already-did-so type of behavior) fall under an implementation extension, then?

Re: Undefined behavior in C is a reading error

#472
post #197

Earlier quoted context omitted.

C was created during a time where instructions were executed linearly with no vectorization, memory was a flat space with no CPU caches, and there wasn’t a branch predictor that may or may not execute the correct program branch in advance. The list goes on but the rest is beyond my scope. C was designed for a now obsolete computer architecture model and over the years this old model has essentially become an abstract…

The Chisnall article is a tutorial in incorrect Computer Architecture. PDP11s had caches by the 1970s and always had memory management. IPL was invented in the 1960s and has nothing to do with C. Branch predictors were invented in the 1960s too and one of the first machines C was ported to was the IBM370 which had super sophisticated IPL. Etc.

ILP, sheesh

Re: Undefined behavior in C is a reading error

#473
post #465

Earlier quoted context omitted.

The Chisnall article is a tutorial in incorrect Computer Architecture. PDP11s had caches by the 1970s and always had memory management. IPL was invented in the 1960s and has nothing to do with C. Branch predictors were invented in the 1960s too and one of the first machines C was ported to was the IBM370 which had super sophisticated IPL. Etc.

I was unaware. Thank you for the correction! Do you have any further reading on this topic?

I am sorry to say, I do not have a good short reference. There has to be one, though, I hope. The Hennesey Patterson books are the standard intros.

Re: Undefined behavior in C is a reading error

#474

Earlier quoted context omitted.

I don't mean to be snide, but there's no paper on it because it's pretty much something you can learn in compiler 101. Without being able to assume that UB doesn't happen, useful optimizations become impossible very quickly.

You are being snide and inaccurate. Studies show 80% or more of GCC optimization improvements come from the core simple methods. Trying to compensate for the lack of data to support your argument by claiming (falsely) it's taught in an elementary course is weak.

Please link these studies, or describe your "core simple methods", because it is likely that they rely on programs not exhibiting undefined behavior. I mean, even the most simple optimizations like eliminating unused variables or inlining functions (what if you reach into the stack to detect these?) fall apart. These were taught within the first couple weeks of my compiler optimizations class, and I certainly hope that they were part of yours, because I can't imagine what you could have possibly gone over without starting off with this.

Re: Undefined behavior in C is a reading error

#475

Earlier quoted context omitted.

Wang et al tried this an experiment and found no serious wins.

For reference, [0] appears to be the referenced paper. The relevant passage: > To understand how disabling these optimizations may impact performance, we ran SPECint 2006 with GCC and Clang, respectively, and measured the slowdown when compiling the programs with all the three -fno-* [-fno-strict-overflow, -fno-delete-null-pointer-checks, and -fno-strict-aliasing] options shown in Figure 9. The experiments were condu…

> If we change the type of k to size_t, then we no longer observe any slowdown with the workaround options

Basically in that case the benefits of the optimization disappears once you fix the code.

Re: Undefined behavior in C is a reading error

#476
post #371

Earlier quoted context omitted.

What is the meaning of use(*p) in case p is null? what should the compiler emit?

> What is the meaning of use(*p) in case p is null? It dereferences a null pointer, invoking undefined behaviour, then calls the function `use` with the resulting value. > what should the compiler emit? Probably something to the effect of: ld r0 [sp+.p] # if p is not already in a register ld r0 [r0] # *p jsr use but it would be fine to emit something like: ld r0 [sp+.p] # if p is not already in a register jz r0 .pani…

[deleted]

Re: Undefined behavior in C is a reading error

#477
post #391

Earlier quoted context omitted.

I think that's unfair. The taint is 100% on the C++ side of things. Hopefully the newer compiled languages will kill C++.

Nope, the tait lies 100% on the copy-paste compatibilty with a C subset.

All you've done here is show that with C the concept of the l-user is still around.

Re: Undefined behavior in C is a reading error

#478
post #312

Earlier quoted context omitted.

As brilliantly said further in this thread by someone else, maybe check that something is OK before doing it. In that case, something like: [...] if (a > INT_MAX - 1) abort(); int b = a + 1; [...]

> As brilliantly said further in this thread by someone else, maybe check that something is OK before doing it. Much easier said than done: https://github.com/postgres/postgres/blob/master/src/include...

Good point that checking for overflow of a multiplication beforehand is hard. But I don't think checking after the fact would be much easier. So thus a C modification to remove the undefined behavior probably wouldn't be very useful still.

Re: Undefined behavior in C is a reading error

#479

Earlier quoted context omitted.

Nice. If you like, could you explain again what the perceived difference is to adding if (offset >= INT_MAX - 16) fail(); in foo()? (I mean, besides the fact that the size of the buffer pointed to by arr is highly unlikely to agree exactly with either INT_MAX or UNIT_MAX.)

I wanted to show that we don't need UB justified deletes to get good code generation. There was no need to break all that working code when we could have just told people that size_t counters worked better in loops on x86-64 than ints. A lot of C optimization could work that way - relying on cooperation between the compiler and programmers. Java can't do that because Java programmers rely on complex abstractions that…

> A lot of C optimization could work that way - relying on cooperation between the compiler and programmers.

That is precisely how it works already. The reason your code has no bounds checks is exactly because the compiler can assume that you have done your part and ensured that all indices are in bounds. This is what "the compiler can ignore UB" is all about.

The signed integer kerfuffle is just the same: The compiler assumes your cooperation in ensuring, beforehand, that your signed arithmetic never overflows. Its part of the bargain is generating the best possible code it can. Another part of its bargain is offering you the -fwrapv flag to communicate more about your expectations. A third part of the bargain is offering you sanitizers that can inform you that you have done something you probably didn't want.

Re: Undefined behavior in C is a reading error

#480

Earlier quoted context omitted.

> As brilliantly said further in this thread by someone else, maybe check that something is OK before doing it. Much easier said than done: https://github.com/postgres/postgres/blob/master/src/include...

Good point that checking for overflow of a multiplication beforehand is hard. But I don't think checking after the fact would be much easier. So thus a C modification to remove the undefined behavior probably wouldn't be very useful still.

The thing is that it's necessary, and (x86, not sure about arm) asm tells you via the d register if not the overflow flag. So why doesn't the C standard arguably provide a misuse-resistant way of doing so? Instead every project having to reinvent it and get it wrong if they do the "obvious" (but wrong) thing.
Post reply on HN