Live data from Hacker News

Clang emits memcpy for std::swap, which can introduce undefined behavior

llvm.org

71–80 of 83 posts

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#71
post #70
post #45

Reading most thread of llvm bugs so far about there "undefined behaviours" I see a pattern. Llvm goal is performance over correction. stop. If old code breaks, it is you played with fire, correct your code to eliminate these undefined behaviours. Stop. We made wonderful coloured warning to help you. Full Stop. Well on one hand I get the point, people played with fire. Code should be "correct" by standards that are em…

Much of the transition has already happened - most applications have already moved on from C to safer languages. What's coming is either the replacement of C libraries (Rust, very careful C rewrites), or perhaps bypassing them entirely (OCaml unikernel work). I would fear more for proprietary systems. Open source is relatively innovative and adaptable.

Still it sounds like the death of portability.

We are kind of crowning the right to rule of the x86 computer industry. llvm is very tied to apple, maybe it can extend to ARM. But it means that some HW platform that may be to old may be difficult to maintain in the future (HPPA, Dec alpha, MIPS, PDP, zseries?).

And some computers have life cycle that are more than 10 years. (Expensive industry robots, telco switches, some medical devices, aeronautic/space CPU, radars, some very old mainframe used for accounting, embedded automation devices)...

Is this push to obsolescence really cool?

Okay critical system already handle the problem, but what about the stuff in the grey zone? Stuff that were not critical but get adopted nonetheless because they just worked and good be updated?

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#72

Earlier quoted context omitted.

A more common case, would be swapping a vector element with the back of the vector and popping it off, which is kinda common.

It was common pre-C++11, but these days you should just be doing a move and pop rather than a swap and pop.

Luckily all existing code has been modernized to C++11 /s.

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#73
post #70
post #45

Reading most thread of llvm bugs so far about there "undefined behaviours" I see a pattern. Llvm goal is performance over correction. stop. If old code breaks, it is you played with fire, correct your code to eliminate these undefined behaviours. Stop. We made wonderful coloured warning to help you. Full Stop. Well on one hand I get the point, people played with fire. Code should be "correct" by standards that are em…

Much of the transition has already happened - most applications have already moved on from C to safer languages. What's coming is either the replacement of C libraries (Rust, very careful C rewrites), or perhaps bypassing them entirely (OCaml unikernel work). I would fear more for proprietary systems. Open source is relatively innovative and adaptable.

> most applications have already moved on from C to safer languages

What applications? I don't think I have anything in my computer that's running on these "safer" languages (not considering C++ or Obj-C "safer").

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#74
post #73
post #70

Earlier quoted context omitted.

Much of the transition has already happened - most applications have already moved on from C to safer languages. What's coming is either the replacement of C libraries (Rust, very careful C rewrites), or perhaps bypassing them entirely (OCaml unikernel work). I would fear more for proprietary systems. Open source is relatively innovative and adaptable.

> most applications have already moved on from C to safer languages What applications? I don't think I have anything in my computer that's running on these "safer" languages (not considering C++ or Obj-C "safer").

Remember 90% of programming is internal tools for businesses, not consumer applications.

(Also in a lot of cases you wouldn't necessarily notice. If you've played a few recent games you've likely run at least one written in C#. I've seen commercial drivers written in Python that you only notice if you look in the internals)

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#75
post #71
post #70

Earlier quoted context omitted.

Much of the transition has already happened - most applications have already moved on from C to safer languages. What's coming is either the replacement of C libraries (Rust, very careful C rewrites), or perhaps bypassing them entirely (OCaml unikernel work). I would fear more for proprietary systems. Open source is relatively innovative and adaptable.

Still it sounds like the death of portability. We are kind of crowning the right to rule of the x86 computer industry. llvm is very tied to apple, maybe it can extend to ARM. But it means that some HW platform that may be to old may be difficult to maintain in the future (HPPA, Dec alpha, MIPS, PDP, zseries?). And some computers have life cycle that are more than 10 years. (Expensive industry robots, telco switches,…

Huh? Higher-level languages are much more portable than C - you only have to port the language runtime, and often someone's done that already. LLVM has a lot of different backends available.

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#76

Earlier quoted context omitted.

It is not the particular situation people are upset about (well, at least me). It is the reasoning, especially in the context of "you shall not write undefined behavior according to the standard even if it should makes sens given the computer you are actually programming" that is usually sent on us regular programmer by compiler authors... :/ Yet they do exactly the same thing, and pretty much casually. And I actuall…

You are tarring all compiler authors with a very broad brush here. Myself and other compiler authors I work with are much more specific in their requests. We do actually define some behavior that the standard doesn't require, and we do document this and tell our users its fine to rely on it. Unfortunately, we also have a lot of really clear experience with this stuff that lead us to two conclusions: 1) When we identi…

> We have real hardware differences for a lot of simple things that make them hard or impossible to give defined behavior for.

Hard or impossible to give _performant_ defined behavior for.

> As an example, shifting left by more bits than the size of the value gives different results on several different platforms.

You could, for instance, always mod the shift by the word size, but possibly at a significant cost.

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#77

Earlier quoted context omitted.

I agree you should be able to opt-in to a safety level. For example most programmers do expect signed integer overflows to follow 2s compliment behavior - regardless of what the standard says. There really seems to be a large disconnect between the tool writers and the users of said tools. I've had countless discussions with compiler writers where we've essentially talked passed each other. The compiler writer arguin…

Keep in mind that the compiler doesn't always know whether code is undefined or not. Is x+y at risk of overflow? Maybe, depending on some logic in a separate compilation unit. So what your asking is to define behavior for all code, such that the compiler can prove locally that's it's well-defined. That's not a crazy idea, and a lot of languages do that. But C counts itself as special, for better or worse. I think we…

The problem is that C compilers don't bother proving anything, when it comes to taking advantage of what is defined.

For instance, if x is signed, a C compiler can assume that x + 1 produces a value which is greater than x, and optimize accordingly. It's up to the programmer (and failing that, user) to ensure that x is less than INT_MAX prior to the execution of that x + 1. In fact there is a proof involved, but it is trivial. The compiler assumes that x + 1 > x because, by logical inference, the only way this can be false is if x == INT_MAX. But in that case, the behavior of x + 1 is undefined, and so, who cares about that; it is the programmer's responsibility that this is not the case. Q.E.D.

Rather than require compilers to implement complicated proofs, which essentially consists of a whole lot of work whose end result is only to curtail optimizations, it's far simpler to have ways in the language to tweak the semantics.

If there is a safe mode in which x + 1 is well-defined, even if x is INT_MAX, then the compiler can no longer assume that x + 1 > x. That assumption is simply off the table. (Now the difficult work of proof kicks in if you still want the same optimization: the compiler can still optimize on the assumption that x + 1 > x, but that assumption can be false, yet x + 1 can be well-defined! If an assumption can be false in correct code, then you have hard work to do: you must prove the assumption true before relying on it.)

This safe mode is not linked to optimization level. Unless turned off by the programmer, it is in effect regardless of optimization level.

Right now we have a situation in which compiler optimization or "code generation" options are used for controlling safety. Programmers know that de facto these options affect the actual semantics of C code, and so they get used that way. We know that if we tell GCC "-fno-strict-aliasing", we are not simply defeating some optimizations, but we are in effect requesting a C dialect in which cases of certain aliasing are well defined.

This is a poor situation. Why? Because it's nonportable (the next compiler you use after GCC might not have this option). But, more importantly, semantics and optimization must be decoupled from each other. We pin down the semantics we want from the language (we pin down what is well-defined), and then optimization preserves that semantics: whatever is well-defined behaves the same way regardless of how hard we optimize.

Semantics and optimization have to be independently controlled.

That is how you can eat your cake and have it too. If you think some code benefits from an optimization which assumes that x + 1 > x, you just compile that under suitable semantics. Then if you don't ensure x < INT_MAX, it's really your fault: you explicitly chose a mode in which things break if you don't ensure that, and then you didn't ensure that.

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#78

Earlier quoted context omitted.

Keep in mind that the compiler doesn't always know whether code is undefined or not. Is x+y at risk of overflow? Maybe, depending on some logic in a separate compilation unit. So what your asking is to define behavior for all code, such that the compiler can prove locally that's it's well-defined. That's not a crazy idea, and a lot of languages do that. But C counts itself as special, for better or worse. I think we…

The problem is that C compilers don't bother proving anything, when it comes to taking advantage of what is defined. For instance, if x is signed, a C compiler can assume that x + 1 produces a value which is greater than x, and optimize accordingly. It's up to the programmer (and failing that, user) to ensure that x is less than INT_MAX prior to the execution of that x + 1. In fact there is a proof involved, but it i…

That's a good point, and a lot of languages use that philosophy.

C has a number of things that have kept it going. Let's get some real alternatives that address those reasons.

Or, you can look at Ada and rust, which are closer to what you want.

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#79
post #75
post #71

Earlier quoted context omitted.

Still it sounds like the death of portability. We are kind of crowning the right to rule of the x86 computer industry. llvm is very tied to apple, maybe it can extend to ARM. But it means that some HW platform that may be to old may be difficult to maintain in the future (HPPA, Dec alpha, MIPS, PDP, zseries?). And some computers have life cycle that are more than 10 years. (Expensive industry robots, telco switches,…

Huh? Higher-level languages are much more portable than C - you only have to port the language runtime, and often someone's done that already. LLVM has a lot of different backends available.

hum.... well. If you imagine that they are 100% idempotent on every platform and 100% fully supported. It would work.

But as I stated in my example python/Perl/C# and probably others are in the language support dropping either some platform or supporting only x% of the feature on some platform...

I dare you to access you services using C#/mono on openBSD.

Re: Clang emits memcpy for std::swap, which can introduce undefined behavior

#80

Earlier quoted context omitted.

The problem is that C compilers don't bother proving anything, when it comes to taking advantage of what is defined. For instance, if x is signed, a C compiler can assume that x + 1 produces a value which is greater than x, and optimize accordingly. It's up to the programmer (and failing that, user) to ensure that x is less than INT_MAX prior to the execution of that x + 1. In fact there is a proof involved, but it i…

That's a good point, and a lot of languages use that philosophy. C has a number of things that have kept it going. Let's get some real alternatives that address those reasons. Or, you can look at Ada and rust, which are closer to what you want.

[deleted]
Post reply on HN