News for hackers. Stuff that matters.
Re:Introducing a new, advanced Visual C++ code optimizer by protomikron on Thursday May 05, 2016 @07:22PM (#11640467)
Interesting. Can anybody explain in a few sentences (if this is possible), why we have undefined behaviour in the first place? I know there are optimization reasons, but do we have data that confirms that turning on stricter flags (I think all major compilers let you avoid undefined behaviour) breaks lots of software?
Re:Introducing a new, advanced Visual C++ code optimizer by PeCaN on Thursday May 05, 2016 @09:03PM (#11640956)
(Not guaranteed to be correct)

Long story short: historical accident. Modern safe systems languages like Rust and Ada¹ avoid undefined behavior unless you explicitly ask for unsafe code, and even then there aren't many _undefined_ things you can do (violate strict aliasing I guess).

Most undefined behavior could be implementation-defined, but the edge cases from porting C+Unix from the PDP-11 (which I understand to have been... quirky) to many other systems happened before the spec, then the spec authors had to make the Ideal C Machine a sort of subset of all the existing behaviors. Thus, some things that could've been implementation-defined ended up totally undefined (god knows what computers did on signed overflow back then—the compiler may not have been able to guarantee anything: hence undefined) and we've kinda stuck that way ever since.

That said, the people who shame the compiler writers for "exploiting undefined behavior to optimize microbenchmarks and look good" annoy me to no end. That's just how the spec turned out, put up or shut up (or use a nicer language that isn't trying to stab you in the back as soon as you let down your vigilance...).

Here's a fun history of C: http://pastebin.com/UAQaWuWG

¹ Strictly speaking, I recall the Ada spec has some wording similar to undefined behavior, but it's not something you hit often.

Re:Introducing a new, advanced Visual C++ code optimizer by kibwen on Thursday May 05, 2016 @11:16PM (#11641440)

  > even then there aren't many _undefined_ things you can do
There's actually plenty of things you can do in an `unsafe` block in Rust that counts as undefined behavior (I don't know how you "explicitly ask for unsafe code" in Ada, but I'm confident the same is true there as well). Some of this falls out of the fact that Rust compiles down to LLVM IR, which itself has undefined behavior, but others are inherent (like demanding the preservation of the aliasing guarantees, as you mentioned).

For anyone curious about seriously using unsafe code in Rust (which is to say, using unsafe code in Rust at all, in any capacity), I recommend reading through the Rustonomicon: http://doc.rust-lang.org/nightly/nomicon/

Re:Introducing a new, advanced Visual C++ code optimizer by pjmlp on Friday May 06, 2016 @12:31PM (#11645025)
> I don't know how you "explicitly ask for unsafe code" in Ada

You need to import a virtual package and some times also make use of specific pragmas.

Ada, and Modula-3 are very much "into your face" in what concerns unsafe code.

For example, if you intend to do a conversion between data types without guarantee that the target can can hold a valid data representation, you need to import Ada.Unchecked_Conversion.

And do something like this:

http://www.adaic.org/resources/add_content/docs/95style/html...

Same applies to everything else deemed unsafe.

Re:Introducing a new, advanced Visual C++ code optimizer by Ono-Sendai on Thursday May 05, 2016 @08:07PM (#11640699)
Undefined behaviour allows faster code. It also allows handling of situations that would otherwise have to be defined in some 'awkward' way, such as throwing an exception on out-of-bounds array reads.

Edit: To add to my reply - for example, Java has almost no undefined behaviour. (The single exception AFAIK is some kind of multithreaded data race situation). The cost paid is that e.g. bounds checks must be done (in general) on array accesses, as the behaviour is defined to be an exception thrown in that case. Similarly for null reference dereferences.

Re:Introducing a new, advanced Visual C++ code optimizer by pjmlp on Friday May 06, 2016 @12:36PM (#11645060)
Yes, but for 99% of code written out there there is nothing to gain from faster code due to undefined behaviour.

I am coding since the mid-80's, always been a fan of Algol lineage of programming languages, with C++ being the only exception to it, as it allows many similar features.

Never have I had a situation where better performance thanks to undefined behaviour was an advantage for the use case we were trying to solve.

I think outside games, HPC and winning compiler benchmarks there hardly an advantage exploiting it.

Re:Introducing a new, advanced Visual C++ code optimizer by pcwalton on Friday May 06, 2016 @08:53PM (#11647797)
> Yes, but for 99% of code written out there there is nothing to gain from faster code due to undefined behaviour.

That's not true. Load-load forwarding benefits tons of code that isn't "games, HPC, or compiler benchmarks".

Re:Introducing a new, advanced Visual C++ code optimizer by pjmlp on Saturday May 07, 2016 @03:23AM (#11648730)
Sorry if I disagree.

If the solution delivered is within the time constrains required by the customer, any time spent optimizing ms out of the application is just wasted money.

Re:Introducing a new, advanced Visual C++ code optimizer by jbb555 on Friday May 06, 2016 @06:11AM (#11642823)
It's because C is supposed to be a thin wrapper over the CPU. So when you write '+' on two ints, it's supposed to do whatever the CPU's ADD instruction does. This can vary from CPU type to CPU type and the standard didn't want to impose behavior on an implementation that would be impossible or slow to implement on a given CPU.

For example most CPUs wrap from most positive to most negative on integer overflow, but one kind might just clamp the value at the most positive value. Or give an error, so forcing them to behave in a given way would make it hard to write efficient C programs on some platforms.

Recently some compiler writers decided that they could interpret undefined behavior to mean "Do anything we like".

So for example a sane compiler on x86-64 would compile this :-

    int test(int x)
    {
        return(x > x + 1)
    }
into a code which adds one to a variable then compared it with the original, and this absolutely can return both false and true. However compiler writers have gone Aha! Overflow is undefined, so we'll "optimize" this into always returning false. That is faster code, who wouldn't want faster code!

Personally I think this was never the intent of the standard and compiler writers are abusing the meaning of undefined in order to sneak in optimizations but realy they are just producing compilers that are less and less trustworthy as they no longer do that people want or need.

Re:Introducing a new, advanced Visual C++ code optimizer by gratilup on Friday May 06, 2016 @07:42AM (#11643206)
That's why that patterns is not applied in the new optimizer, unless the Bit Estimator proves x+1 does not overflow. After it was implemented to behave like what other compilers do, I analyzed several applications and libraries and it would have introduced silent security problems - I explained in the blog post.
Re:Introducing a new, advanced Visual C++ code optimizer by rkangel on Friday May 06, 2016 @05:57AM (#11642780)
Undefined behaviour exists because the creators of the C language wanted to leave compiler writers as much flexibility as possible to ensure that they produced code that was fast.

C was always a language that was intended to be used across multiple hardware targets and different processors have different behaviours. Restricting behaviour on certain arithmetic operations might require slow code to 'work around' the processor and generate compliant code. The creators didn't want that so specified as little as possible, leaving the rest to be 'Undefined'.

Re:Introducing a new, advanced Visual C++ code optimizer by matthewaveryusa on Thursday May 05, 2016 @10:06PM (#11641193)
Signed data implies that at least 1 bit represents the signess of the underlying bytes. C did not want to impose which bit must represent the sign of the integer because that may have implications on the performance of hardware that was built to represent signess a different way.
Re:Introducing a new, advanced Visual C++ code optimizer by ahoka on Friday May 06, 2016 @06:35AM (#11642902)
It's a bit more complicated than that (in case of two's complement). BTW, is there anything modern that's not using two's complement?
Re:Introducing a new, advanced Visual C++ code optimizer by gsnedders on Saturday May 07, 2016 @12:23PM (#11650169)
Pretty sure some DSPs don't. (In most cases of "is there anything modern", the answer is some DSP.)