Live data from Hacker News

On C-optimizing compilers removing code that has undefined behavior

yodaiken.com

31–40 of 71 posts

Re: On C-optimizing compilers removing code that has undefined behavior

#31
Uhm, I'm pretty sure this page is wrong, and the compiler cannot optimize this out. An "indeterminate" value is either an unspecified value or a trap representation. Like they said, the value here cannot be a trap representation, so it's just an unspecified value. An unspecified value is merely an unknown value, NOT a dynamically-mutating value, and NOT a trap representation. So XORing an unspecified value with itself must result in zero, not undefined behavior. (UB would occur with a trap representation, which this isn't.)

Re: On C-optimizing compilers removing code that has undefined behavior

#32
post #5

> The programmer has clearly attempted to set x[0]=0 Then why not just write it like that? This is like deliberately shooting yourself in the foot and complaining that your shotgun works.

The problem is that the language allows this code and the compiler accepts it. If the code really does make no sense, then why not disallow it or capture it with a compiler warning? Instead the optimizer is to silently remove the code. Isn't it possible that the programmer knows something that the optimizer is unaware of?

The standard can't mandate a diagnostic for undefined behaviour, because it's not always possible to determine if behaviour is undefined. (Turing completeness) However, an implementation is allowed to issue any diagnostics it likes, so if you want one for this case, bug your compiler vendor to add one. Or, check the manual - it's possible that your compiler already does issue a diagnostic if you turn the right warnings on.

Re: On C-optimizing compilers removing code that has undefined behavior

#33
post #15

The author quotes an article referring to using uninitialized memory for additional entropy and that article cites [10]. Let me just say: DON'T do that, ever. Uninitialized memory is rarely random. If you're lucky, it's quasi-constant because your own program always writes something else to it before. Worst case an attacker manages to write something to that memory before you read it, thereby controlling part of your…

Actually some well know researchers are quite known to be against UB, but C compiler writers don't seem to be willing to listen to them.

https://blog.regehr.org/archives/1054

Re: On C-optimizing compilers removing code that has undefined behavior

#34
post #12

Earlier quoted context omitted.

> but I will still like C to be as self explanatory as possible. C is not self-explanatory at all and without good knowledge of the standard anyone will write broken code that will fall apart sooner or later. C is not a simple language, nor one with simple semantics. Without knowledge of the standards it is essentially not possible to write portable C code.

I was thinking about reading the code line by line. Name any other language in which you can do that, without spending at least a week in that. I don't know what is a simple language according to you, but according to me C seems quite a simple language. Not saying it means that a good quality code is easier to write in C.

I can't, but I also think your premise is not correct ("reading the code line by line" "without spending at least a week in that"). A lot of production C code is inscrutable without a good understanding of the language, and to understand many common constructs (e.g. overflow checks) you just have to know it. That trivial code is trivial to understand... well... that's true in most languages, no?

Re: On C-optimizing compilers removing code that has undefined behavior

#35
post #25

Undefined behaviour was always there to make possible compilers to optimize as they like (nowadays usually for speed or to ease porting to specific architectures) - that is the essence of C "portable assembly" mentality and it always was. Am I wrong? I tolally agree that this is a bad mentality for software developement in general, but at least it is the "authentic C way" so I feel that part of the critics ungrounded…

[deleted]

Re: On C-optimizing compilers removing code that has undefined behavior

#36
post #5

> The programmer has clearly attempted to set x[0]=0 Then why not just write it like that? This is like deliberately shooting yourself in the foot and complaining that your shotgun works.

The problem is that the language allows this code and the compiler accepts it. If the code really does make no sense, then why not disallow it or capture it with a compiler warning? Instead the optimizer is to silently remove the code. Isn't it possible that the programmer knows something that the optimizer is unaware of?

> If the code really does make no sense, then why not disallow it or capture it with a compiler warning?

You answered your own question:

> Isn't it possible that the programmer knows something that the optimizer is unaware of?

Here's a fun exercise. Find the best static analyzer you can. Run it on some substantial body of C code. Count all the false positives and false negatives (good luck).

Now you should have an idea as to why you can't simply require the compiler to reject the code and issue a diagnostic. But making code like this UB is about as close you can get to "disallowing it."

Alternatively you could try to eliminate the problem entirely by removing the whole concept of uninitialized memory and requiring that all variables are initialized to some value per default. Depending on which camp you're in, this is a step forward or a step back. Some people just see the words UB and think it is Satan, bad bad bad. For them this is a step forward.

But if all variables are supposed to have a definitive starting value, compilers & static analyzers suddenly can't warn you about the cases where it can tell you forgot to initialize something, because all of a sudden such code is totally legit. The analyzer can't tell whether you forgot to make an initialization or whether you're actually intentionally relying on the default value.

That's a big step back as far as I am concerned. You eliminate a problem because "UB is bad!" and create another problem we can't even issue warnings for, without potentially generating loads of false positives.

Now if one wanted to complain that his compiler detects an obvious case of UB and doesn't warn him about it, he should take it up with the compiler developers (or see if he can help himself by turning on the right flags). Alternatively one could invest in a good static analyzer. The standard committee can't really fix this problem without making substantial changes to the language. Instead I'm glad they allow relatively simplistic implementations that don't do deep advanced analysis.

Re: On C-optimizing compilers removing code that has undefined behavior

#37
post #11

You don't get to write C and complain about UB breaking your code at the same time.

you do in my opinion, i don't understand why UB is so foundamental to C, in this case woudn't a compiler warnig or error be better?

UB is pretty damn fundamental to C. Not many people realize it though. It's the fundamental difference between C and C++ compared to Python or C# or Java or Rust or whatever.

Re: On C-optimizing compilers removing code that has undefined behavior

#38
post #33
post #15

The author quotes an article referring to using uninitialized memory for additional entropy and that article cites [10]. Let me just say: DON'T do that, ever. Uninitialized memory is rarely random. If you're lucky, it's quasi-constant because your own program always writes something else to it before. Worst case an attacker manages to write something to that memory before you read it, thereby controlling part of your…

Actually some well know researchers are quite known to be against UB, but C compiler writers don't seem to be willing to listen to them. https://blog.regehr.org/archives/1054

In the Botan example, masking the operands instead of branching causes GCC to emit no additional code.

Re: On C-optimizing compilers removing code that has undefined behavior

#40
post #17

I am 100% in agreement with the C standard committee on this one. Treating all use of uninitialized memory as undefined behavior is a reasonable limitation that gives compiler writers a great deal of flexibility to improve performance. If the only loss is the ability to use uninitialized memory as a source of entropy for random number generators, then that is an incredibly low price to pay for the increased performan…

Then why isn't the code being disallowed? Why is it being silently removed in the middle of the night through an optimization back door?

It is disallowed by the standard.

It's not disallowed by compilers, because they're deficient. In this case I'd guess compiler front-end doesn't track which values in an array are initialized, and when optimizing back-end sees UB it's too late to emit an error.

Post reply on HN