Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

681–690 of 748 posts

Re: Everything in C is undefined behavior

#681

Earlier quoted context omitted.

Is that really a meaningful distinction? Once you are addressing arbitrary values you are firmly in the realm of "anything happening" in practice, but you've now given up optimization opportunities. As has been repeatedly demonstrated over the years, once memory safety breaks it is practically impossible to make any guarantees about program behavior.

Yes, it's a meaningful distinction. No you are not into "anything happening" in practice. Your compiler emitting a load operation and it failing isn't "anything". The failure being handled by code that the compiler authors can't predict doesn't make it "anything". And if you lose optimization opportunities because of this it's because your optimization is broken. By the way, if you lose optimization opportunities bec…

I mean... You can turn a one byte out of bounds write into code execution.

https://daniel.haxx.se/blog/2016/10/14/a-single-byte-write-o...

And if you get code execution, then you by definition have "anything".

Re: Everything in C is undefined behavior

#682

Earlier quoted context omitted.

How do you propose to predict the behavior of a true race condition with only the binary, faithfully translated by the compiler? Moreover, this is at best an incredibly pedantic point, not something that changes how programmers need to approach UB. You can't review the source code of a compiler that hasn't been written yet.

It's fully defined by your CPU's silicon masks and your compiler's binary code that one of several things will happen.

Turns out that when you're implementing network applications, the set of things that could happen also depends on what the script kiddie on the other side of the globe feels like this morning.

Some would prefer less excitement than this.

C code should be more predictable and easier to reason about than using a macro assembler. To the extent it is not, the language has failed.

Re: Everything in C is undefined behavior

#683

C is still, by far, the simplest language that we have. Although many newer languages are safer (with the exclusion of Rust, primarily by being slower) the same kinds of issues that are there in C are there in these languages, their effects are just harder to see. People complain about C as though they know how to fix it.

C is not a simple language in the sense that writing software in C is simple, and I think that's the only useful way to understand the word "simple" in this context. Brainfuck is "simple" by any other definition as well, but that's not a useful quality.

another useful sense is easy to understand/read what programmer want to write. (ofc exclude mad code with macros etc).

Brainfuck is absolutely not simple in this case

Re: Everything in C is undefined behavior

#684
post #22

Earlier quoted context omitted.

Notice though "ignoring the situation" thru "documented manner characteristic of the environment". Even though truly you can read this in an uncharitable way, you could also try and understand the intent of this paragraph, and I think reading it for its intents is always the best way to interpret a language standard when the wording is ambiguous or soft, especially if you're writing a compiler. I don't think you coul…

> Notice though "ignoring the situation" thru "documented manner characteristic of the environment". I noticed that. Those are 100% consistent & implied by the parts of the standard I quoted that you are ignoring, though. What you're doing is: - Arguing is that those phrases describe the totality of the implications, rather than mere examples, without providing anything to base this method of argumentation on. - Comp…

> Completely ignoring the other phrases I quoted, which (taken at face value) contradict your reading.

You are taking them out of context (literally this is what you describe here, taking at face value a smaller quote).

I think your approach to interpreting the spec is not correct. This isn't code, it's a spec: it needs to be read in full context (even though a good spec would certainly be written in a less context-sensitive way, this is not a perfect spec -- have you ever seen one?). You're not a computer or a machine, you need to read it more like a human, even though we're all trained on the concrete mechanics of computer programming. Yes, even though it's describing a programming language, believe it or not. All specs have flaws and need nuance in those situations or you will either (for language specs) write code that doesn't work anywhere, or you will write a compiler that breaks code matching what the authors of the spec intended to allow.

> Right now it looks like you have an impression of UB that doesn't match reality.

I have an impression of UB that is not the convention, my post is criticising the convention. I am trying to give context and nuance where it is unfortunately lacking and now apparently quite relevant to lots of people. This can't change reality of current compilers, but maybe it can serve as a lesson in history.

Re: Everything in C is undefined behavior

#685

Earlier quoted context omitted.

Strings typically consist of UTF-8 bytes, and any old `char*` pair has no alignment guarantees.

That's true, and that's why your typical string vector code has a prelude and a postlude to do the incomplete chunks at the ends. Between the ends, it's processing larger self-aligned chunks.

If you're aware of that technique, why were you asking about use cases for unaligned loads?

Re: Everything in C is undefined behavior

#686
post #646

Earlier quoted context omitted.

Excuse me, what? I was writing both C and C++ 20 years ago, and UB was a huge part of the conversation (and the curriculum) back then as well. There were a few high-profile "scandals" around GCC 3.2 (IIRC) because the compiler finally started much more aggressively using UB in optimizations, which was a reason that lots of people stayed on GCC 2.95 for a very long time. GCC 3.2 came out in 2002.

“More aggressively using UB” isn’t the right way to think about it. In the C ecosystem, the compiler gets to define what UB means. They broke compatibility with their previous UB semantics, then blamed the language spec.

> In the C ecosystem, the compiler gets to define what UB means.

It really doesn't though. The current revision of the ISO/IEC 9899 standards document gets to define it, nobody else.

Re: Everything in C is undefined behavior

#687

Earlier quoted context omitted.

That's true, and that's why your typical string vector code has a prelude and a postlude to do the incomplete chunks at the ends. Between the ends, it's processing larger self-aligned chunks.

If you're aware of that technique, why were you asking about use cases for unaligned loads?

I'm saying that string search algorithms are _not_ a legitimate use case for unaligned loads.

Re: Everything in C is undefined behavior

#688

Is there a way to avoid undefined behavior Im C then? Could we write a new C compiler that adds some checks and fixes (e.g. raise documented exceptions) to each undefined behavior?

ubsan. Doesn't catch all of it.

Will take a look thanks!

Re: Everything in C is undefined behavior

#689

Earlier quoted context omitted.

> They understand that all types "are" just bytes and that all pointers "are" just register-sized integer addresses, because that's how the hardware works and has worked for decades. I'd clarify this with "They understand that all values are just bytes" . > Meanwhile, the actual computers we have been using for decades have no problems actually just loading 4 bytes through any arbitrary pointer with zero overhead. It…

> A clear majority of the UB problems with C could be fixed if the standards committee slowly moved all UB into IB There is no such thing as getting rid of "all UB." What behavior is the implementation supposed to prescribe for a write to an unpredictable garbage address you read from the network? It could overwrite your code. It could overwrite any value anywhere. It could overlap with anything. Prescribing defined…

> What behavior is the implementation supposed to prescribe for a write to an unpredictable garbage address you read from the network? I

"The compiler is not allowed to elide a write to a garbage address".

Wasn't that easy?

Re: Everything in C is undefined behavior

#690

Earlier quoted context omitted.

> What if the compiler is able to use that to determine that a whole code path is dead, Then it should warn "unreachable code". > and then significantly improve the surrounding function because of that? It's not simply the removal that is the problem, it's that the code is silently removed.

I don’t mean this in a rude way but you should really read the posts I linked, it’s interesting and part 3 especially answers these questions Direct link to part 3 (but read the others first for context if you can): https://blog.llvm.org/2011/05/what-every-c-programmer-should... You don’t want warnings for every piece of code in a library you’re not using or sanity check you added that isn’t supposed to be hit And yo…

> I don’t mean this in a rude way but you should really read the posts I linked, it’s interesting and part 3 especially answers these questions

I have read the entire series. Both in the past and more recently.

> If you warned whenever undefined behaviour could be happening then e.g. every single pointer deference would say “warning: compiling assuming pointer is not null or unaligned”

I am not proposing that at all, I am proposing (which the series you link to does not preclude) that eliding code on the basis of UB can be determined by the compiler. If the compiler can determine that some code block needs to be elided, then the reason for that elision has already been determined, in which case it can issue a warning when "reason" == "pointer already used" when eliding the null check.

Post reply on HN