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.
Undefined Behavior in 2017
21–30 of 120 posts
Re: Undefined Behavior in 2017
#22> 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
#23Earlier 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.
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
#24Earlier 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/.
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
#25How many of these 200+ undefined behaviours exist in more modern low-level languages, such as Rust and D?
Re: Undefined Behavior in 2017
#26How 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…
Re: Undefined Behavior in 2017
#27Earlier 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.
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
#28How many of these 200+ undefined behaviours exist in more modern low-level languages, such as Rust and D?
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
#29Earlier 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).
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
#30How 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