Live data from Hacker News

Undefined Behavior in 2017

blog.regehr.org

21–30 of 120 posts

Re: Undefined Behavior in 2017

#21
post #10
post #8

Earlier quoted context omitted.

Some undefined behaviours relate to runtime values. !iirc! signed 2+2 is safe but signed SIGNED_INT_MAX + 1 is not.

But it is easy to give it a defined behavior on a particular architecture. For example, on x86-64, it can be defined to overflow just like unsigned does. The compiler can emit errors about the code if it is compiled to a different architecture where the same defined behavior is too expensive to implement.

How would that help? The behavior would be defined, but it still wouldn't be what you /want/.

Re: Undefined Behavior in 2017

#22
The main message from my point of view:

> Be knowledgeable about what’s actually in the C and C++ standards since these are what compiler writers are going by. Avoid repeating tired maxims like “C is a portable assembly language” and “trust the programmer.”

> Unfortunately, C and C++ are mostly taught the old way, as if programming in them isn’t like walking in a minefield. Nor have the books about C and C++ caught up with the current reality. These things must change.

Re: Undefined Behavior in 2017

#23
post #19
post #17

Earlier quoted context omitted.

It is very easy to be efficiently determined at compile time, other systems programming languages do it, by not having UB on their language standard to start with. If people prefer "performance trumps correctness" and "winning compiler benchmarks is what counts" then they should happily keep getting exploited.

I do see your point, but that'd be a different language. With the standardised C we have, it's not easy.

Which is why we should move away from it.

However I don't see it ever happening in the UNIX world, only on OSes whose architecture is not bound to the traditional UNIX/C culture.

Which is why see as positive that Apple, Google and Microsoft are pushing C and C++ down into the very lowest layers of their OS stacks, mostly visible on Google's case.

Even straight pure Assembly programming has less UB surprises.

Re: Undefined Behavior in 2017

#24
post #10

Earlier quoted context omitted.

But it is easy to give it a defined behavior on a particular architecture. For example, on x86-64, it can be defined to overflow just like unsigned does. The compiler can emit errors about the code if it is compiled to a different architecture where the same defined behavior is too expensive to implement.

How would that help? The behavior would be defined, but it still wouldn't be what you /want/.

Defined good behavior > defined bad behavior > undefined behavior.

This article is about attacking the last category.

Unsigned overflow is far less of a problem than signed overflow because it is defined.

It is very cheap to make signed overflow defined. It is more expensive to detect it and fail at runtime.

Re: Undefined Behavior in 2017

#25
post #2

How many of these 200+ undefined behaviours exist in more modern low-level languages, such as Rust and D?

LuaJIT is another modern low-level language. It has some remarkable undefined behavior like the evaluation order for function arguments. Scares me a bit.

https://github.com/LuaJIT/LuaJIT/issues/238

Re: Undefined Behavior in 2017

#26
post #2

How many of these 200+ undefined behaviours exist in more modern low-level languages, such as Rust and D?

In Rust it's pretty limited. Here is the full list, from the Rustonomicron: Dereferencing null or dangling pointers Reading uninitialized memory Breaking the pointer aliasing rules Producing invalid primitive values: dangling/null references a bool that isn't 0 or 1 an undefined enum discriminant a char outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF] a non-utf8 str Unwinding into another language Causing a da…

An important point: if you provide a safe wrapper around some unsafe code it's up to the programmer to ensure the above is true.

Re: Undefined Behavior in 2017

#27
post #17
post #13

Earlier quoted context omitted.

Because a lot of UB cannot be efficiently determined at compile time. Hence, UBSan.

It is very easy to be efficiently determined at compile time, other systems programming languages do it, by not having UB on their language standard to start with. If people prefer "performance trumps correctness" and "winning compiler benchmarks is what counts" then they should happily keep getting exploited.

> It is very easy to be efficiently determined at compile time

for many cases it is in fact equivalent to the halting problem. What you can do is check at runtime, which has performance implications (from trivial to expensive depending on the check).

Re: Undefined Behavior in 2017

#28
post #2

How many of these 200+ undefined behaviours exist in more modern low-level languages, such as Rust and D?

A lot of undefined behaviour on this list is quite specific to the C programming language, so it would be like comparing apples to oranges. Though, one major impression I think you will get after going through this list is that there is no good reason for making those things an undefined behaviour in the first place. For example, "The result of the preprocessing operator ## is not a valid preprocessing token", really?

Regarding those things that actually matter for programmer, following would be well-behaved in Rust (including unsafe blocks): conversion between types, integer arithmetic, pointer arithmetic (there are generally two variants of operations, one that essentially treats pointers as unsigned integers, and another one that behaves like in C with more opportunities for optimization). On the other side of the coin, in Rust mutable references cannot be aliased.

Re: Undefined Behavior in 2017

#29
post #17

Earlier quoted context omitted.

It is very easy to be efficiently determined at compile time, other systems programming languages do it, by not having UB on their language standard to start with. If people prefer "performance trumps correctness" and "winning compiler benchmarks is what counts" then they should happily keep getting exploited.

> It is very easy to be efficiently determined at compile time for many cases it is in fact equivalent to the halting problem. What you can do is check at runtime, which has performance implications (from trivial to expensive depending on the check).

Not if the language standard doesn't allow for UB to begin with, then there isn't any halting problem to worry about.

This is what the alternatives in the memory safe systems programming language since Algol days do.

Surely they still allow for developers to disable some of those checks explicitly, but then it is the programmers fault to choose "performance trumps correctness" instead of "correctness trumps performance".

Re: Undefined Behavior in 2017

#30
post #25
post #2

How many of these 200+ undefined behaviours exist in more modern low-level languages, such as Rust and D?

LuaJIT is another modern low-level language. It has some remarkable undefined behavior like the evaluation order for function arguments. Scares me a bit. https://github.com/LuaJIT/LuaJIT/issues/238

lua is no way a "low level" language
Post reply on HN