Live data from Hacker News

Undefined behavior in C is a reading error (2021)

yodaiken.com

51–60 of 69 posts

Re: Undefined behavior in C is a reading error (2021)

#51

Earlier quoted context omitted.

Why isn't that fine? The compiler ignored the undefined behavior it didn't detect.

No. No honest person can claim that making a decision predicated on the existence of X is the same as "ignoring" X.

This is the most normal case though, isn't it? Suppose a very simple compiler, one that sees a function so it writes out the prologue, it sees the switch so it writes out the jump tables, it sees each return statement so it writes out the code that returns the values, then it sees the function closing brace and writes out a function epilogue. The problem is that the epilogue is wrong because there is no return statement returning a value, the epilogue is only correct if the function has void return type. Depending on ABI, the function returns to a random address.

Most of the time people accuse compilers of finding and exploiting UB and say they wish it would just emit the straight-forward code, as close to writing out assembly matching the input C code expression by expression as possible. Here you have an example where the compiler never checked for UB let alone proved presence of UB in any sense, it trusted the user, it acted like a high-level assembler, yet this compiler is still not ignoring UB for you? What does it take? Adding runtime checks for the UB case is ignoring? Having the compiler find the UB paths to insert safety code is ignoring?

Re: Undefined behavior in C is a reading error (2021)

#52
post #49

Well, where have we had trouble in C in the past? Usually, with de-referencing null pointers. The classic is char* p = 0; char c = *p; if (p) { ... } Some compilers will observe that de-referencing p implies that P is non-null. Therefore, the test for (p) is unnecessary and can optimized out. The if-clause is then executed unconditionally, leading to trouble. The program is wrong. On some hardware, you can't de-refer…

> This is often implemented with a zero pointer indicating None, but the user doesn't see that.

The Guaranteed Niche Optimisation is, as its name suggests, guaranteed by the Rust language. That is, Option is guaranteed to be the same size as &T. The choice for the niche to be the all-zero bit representation is in some sense arbitrary but I believe it is a written promise too.

Re: Undefined behavior in C is a reading error (2021)

#53
post #20

I think the problem is sort of a permutation of this argument: way way too much attention is being paid to warning about the dangers and inadequacies of the standard's UB corners, and basically none to a good faith effort to clean up the problem . I mean, it wouldn't be that hard in a technical sense to bless a C dialect that did things like guarantee 8-bit bytes, signed char, NULL with a value of numerical zero, etc…

The exercise you suggest is futile. You've assumed that all these C programmers are writing software with a clear meaning and we just need to properly translate it so that the meaning is delivered.

There were C programmers like that, most of them now write Rust. They write what they meant, in Rust it just does what they wrote, they're happy.

But a large number - by now a majority of the die-hard C programmers - don't want that. They want to write nonsense and have it magically work. They don't need a new C dialect or a better compiler, or anything like that, they need fairy tale magic.

Re: Undefined behavior in C is a reading error (2021)

#54
post #30

Earlier quoted context omitted.

Maybe I don't understand something, but for me it seems pretty easy. What is needed to be done: 1. Make a list of all UB 2. Define the sensible compiler behavior in each case (for example, let MAX_INT+1 to calculate into MIN_INT on x86_64, just because `add` on x86_64 does that) 3. Treat this as a part of a standard, when compiling the code. This approach allows to have different compiler behavior on different archit…

That works for a lot of behavior but not everything. For example: int f(int x) { static int y[] = {42, 43}; return y[x]; } What behavior should `f(-1)` or `f(100)` have? What is sensible?

Desugar to pointer arithmetic, try to do an dereference like

    *(y-1)
and more than likely segfault, or return the value at that address if it's somehow valid.

Re: Undefined behavior in C is a reading error (2021)

#55
post #20

I think the problem is sort of a permutation of this argument: way way too much attention is being paid to warning about the dangers and inadequacies of the standard's UB corners, and basically none to a good faith effort to clean up the problem . I mean, it wouldn't be that hard in a technical sense to bless a C dialect that did things like guarantee 8-bit bytes, signed char, NULL with a value of numerical zero, etc…

The exercise you suggest is futile. You've assumed that all these C programmers are writing software with a clear meaning and we just need to properly translate it so that the meaning is delivered. There were C programmers like that, most of them now write Rust. They write what they meant, in Rust it just does what they wrote, they're happy. But a large number - by now a majority of the die-hard C programmers - don't…

> There were C programmers like that, most of them now write Rust.

Please don't. There's a space in the world for language flames. But the real world is filled with people trying to evolve existing codebases using tools like ubsan, and that's what I'm talking about.

Re: Undefined behavior in C is a reading error (2021)

#56
post #13
post #7

Earlier quoted context omitted.

Specifically, undefined behavior is when the compiler vendors couldn't agree whether a particular bit of code should legitimately compile to something or be considered erroneous. Ex.: null pointer access. Clearly an error in user-space programs running on a sophisticated operating system, but in kernel or embedded code sometimes you do want to read or write to memory location 0. So the standards committee just shrugg…

i think the issue is more that in embedded code you can't depend on the hardware to detect an access to any given memory location (the standard does permit the bit pattern of a null pointer to be different from all zeroes, which is what you are supposed to do if you want memory location 0 to be referenceable with a pointer)

No compiler I'm aware of implements non-zero null pointers on systems where address 0 is valid (e.g. armv7), so it ends up being kind of a moot point.

Re: Undefined behavior in C is a reading error (2021)

#57

I really don't like reading these dimwitted screeds. We did not get here because layering over a standard or a document --- this is not the US supreme court or similar. We got here because - There are legit issues trying to define everything without loosing portability. This affects C and anything like it. - Compiler writes do want to write optimizations regardless of whether this is C or anything else --- witness th…

*lawyering over a standard or document

Re: Undefined behavior in C is a reading error (2021)

#58

Earlier quoted context omitted.

> the implementor (compiler writer) has two choices: (a) assume that the undefined behavior doesn’t occur, and implement optimizations under that assumption, or (b) nevertheless implement a defined behavior for it, which in many cases amounts to a pessimization. No. The implementor has three choices: (1) Ignore the situation altogether; (2) behave according to documentation (with or without a warning); or (3) issue a…

What behavior should the following have: int f(int x) { switch (x) { case 0: return 31; case 1: return 28; case 2: return 30; } } This code on its own has no undefined behavior. In another translation unit, someone calls `f(3)`. What would you have compilers do in that case? That path through the program has undefined behavior. However, the two translation units are separate and as such normal tooling will not be abl…

In a new language that isn't C, that function shouldn't compile at all (missing return).

In a C compiler, inserting a trap (x86 ud2, for example) might be reasonable.

Re: Undefined behavior in C is a reading error (2021)

#59
post #13

Earlier quoted context omitted.

i think the issue is more that in embedded code you can't depend on the hardware to detect an access to any given memory location (the standard does permit the bit pattern of a null pointer to be different from all zeroes, which is what you are supposed to do if you want memory location 0 to be referenceable with a pointer)

No compiler I'm aware of implements non-zero null pointers on systems where address 0 is valid (e.g. armv7), so it ends up being kind of a moot point.

yeah, i'm not aware of any instances of it!

Re: Undefined behavior in C is a reading error (2021)

#60
post #55

Earlier quoted context omitted.

The exercise you suggest is futile. You've assumed that all these C programmers are writing software with a clear meaning and we just need to properly translate it so that the meaning is delivered. There were C programmers like that, most of them now write Rust. They write what they meant, in Rust it just does what they wrote, they're happy. But a large number - by now a majority of the die-hard C programmers - don't…

> There were C programmers like that, most of them now write Rust. Please don't. There's a space in the world for language flames. But the real world is filled with people trying to evolve existing codebases using tools like ubsan, and that's what I'm talking about.

I don't see how this constitutes a language flame. I spent decades writing C. Twenty years ago I'd have agreed that it was worth trying to "fix" C, today I just write Rust instead.
Post reply on HN