Live data from Hacker News

I Do Not Know C: Short quiz on undefined behavior (2015)

kukuruku.co

81–90 of 189 posts

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#81
post #76

Earlier quoted context omitted.

What's the point of this?

It allows the optimizer to assume away the halting problem; all nontrivial loops are obligated to halt.

I read this as, will confuse the snot out of hapless newbie programmers trying to learn C via stepping though their code in an IDE. While providing no practical benefit to programmers writing production code.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#83

Earlier quoted context omitted.

This is not really correct. The kinds of implementation dependencies usually encountered reflected processor architecture. The C standards committee and compiler community have created a situation in which different levels of "optimization" can change the logical behavior of the code! Truly a ridiculous state of affairs. The standards committee has some mysterious idea I suppose, but the compiler writers who want to…

Compiler writers have to use program transformation to do well on benchmarks. Developers who don't prioritize benchmarks probably don't use C, and if they do they really shouldn't, because sacrificing correctness for speed is the only thing C is good for these days.

In reality, that's why I think that neither Go nor Rust will ever replace C (Maybe C++, Java or Python), because nothing can replace C.

C worked in the 70s, when a naive compiler + asm would work perfectly.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#84
post #79
post #44

Earlier quoted context omitted.

> What's the best way to "fix" strict aliasing without disabling the undefined behavior around it? Using a union? I had this discussion with another C++ programmer and we came to the conclusion that, if you care to avoid that particular UB, any time you cast pointers between unrelated or basic types and you're going to write to one pointer and read from the other, you need to go through a union, as annoying as it is.

Not just a union, but the union definition needs to be in scope _and_ used such so that the compiler can see the possibility of the relationship between the two objects. But a union doesn't magically make type-punning correct. This code is not correct: union { int d; long long lld; } u; u.d = 1; printf("%lld\n", u.lld); u.lld = 0; printf("%lld\n", u.lld); The union ensures that the compiler doesn't move "u.lld = 0" a…

> The union ensures that the compiler doesn't move "u.lld = 0" above the first print statement, but usually writing from one type and reading from another is undefined behavior no matter how you accomplish it.

I know, but the only reason aliasing becomes an issue is because someone is trying to cast between unrelated pointer types to perform cheap type conversions. Yes, even with the union the behavior is undefined, but if you know the platform you're targeting the program may be well-behaved.

As for your snippets, yes, casting pointers across function boundaries will work. The problem is when you don't want to introduce a call, which is where unions come in.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#85
post #76

Earlier quoted context omitted.

What's the point of this?

It allows the optimizer to assume away the halting problem; all nontrivial loops are obligated to halt.

What's the point of this though? Why are you letting programmers write non-functional code? When does the loop exactly terminate? I'm guessing the standard discusses this but at this point idk if I care about memorizing more C trivia.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#86

Earlier quoted context omitted.

C programmers expect dead code removal. Especially when the compiler also inlines functions (and, of course, inlining makes the biggest impact on short functions; and one way to get short functions is to have aggressive dead code removal). And macros can expand into very weird, but valid, code; so the statement that "nobody would ever write code like that" isn't relevant. The compiler may well have to handle unnatura…

C programmers should be able to expect that "optimizations" will not transform program meaning. And because C is so low level, certain types of optimizations may be more difficult or impossible. If the pointer was explicitly set to NULL, the compiler can justifiably deduce the branch will not be taken but the deduction "if the programmer dereferenced the pointer it must not be NULL" is not based on a sound rule. In f…

> In fact, the whole concept that the compiler can make any transformation it wants in the presence of UB is wacky.

That's the way it's often explained but it's not really what happens--the compiler doesn't scan for undefined behavior and then replace it with random operations. Instead, it's applying a series of transformations that preserve the program's semantics if the program stays "in bounds", avoiding invoking undefined behaviors.

I agree that equating "if the programmer dereferenced the pointer" and "the pointer must not be NULL" betrays a....touching naivety about the quality of a lot of code, but if you start from the premise that the programmer shouldn't be doing that, the results aren't totally insane.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#87
post #76

Earlier quoted context omitted.

It allows the optimizer to assume away the halting problem; all nontrivial loops are obligated to halt.

What's the point of this though? Why are you letting programmers write non-functional code? When does the loop exactly terminate? I'm guessing the standard discusses this but at this point idk if I care about memorizing more C trivia.

> What's the point of this though? Why are you letting programmers write non-functional code?

He just told you. Because the only way to prevent it in general is to solve the halting problem.

> When does the loop exactly terminate?

In the general case this is provably impossible to determine.

(all you're seeing here is that the compiler authors felt no need to add special case logic to handle "trivial" cases of the halting problem. If the compiler sees any expression in a loop test, it assumes the loop will halt some of the time)

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#88

Earlier quoted context omitted.

What's the point of this though? Why are you letting programmers write non-functional code? When does the loop exactly terminate? I'm guessing the standard discusses this but at this point idk if I care about memorizing more C trivia.

> What's the point of this though? Why are you letting programmers write non-functional code? He just told you. Because the only way to prevent it in general is to solve the halting problem. > When does the loop exactly terminate? In the general case this is provably impossible to determine. (all you're seeing here is that the compiler authors felt no need to add special case logic to handle "trivial" cases of the ha…

> He just told you. Because the only way to prevent it in general is to solve the halting problem.

I'm aware. I think that I might have misunderstood what the optimization really does.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#89
post #28

My 'favourite' bit of surprising (not undefined) behaviour I've seen recently in the C11 spec is around infinite loops, where void foo() { while (1) {} } will loop forever, but void foo(int i) { while (i) {} } is permitted to terminate...even if i is 1: > An iteration statement whose controlling expression is not a constant expression, that performs no input/output operations, does not access volatile objects, and pe…

What's the point of this?

If the optimizer can determine that "nothing happens" in the loop, it can optimize the loop away without attempting to determine whether or not the loop terminates.

Re: I Do Not Know C: Short quiz on undefined behavior (2015)

#90

Earlier quoted context omitted.

> What's the point of this though? Why are you letting programmers write non-functional code? He just told you. Because the only way to prevent it in general is to solve the halting problem. > When does the loop exactly terminate? In the general case this is provably impossible to determine. (all you're seeing here is that the compiler authors felt no need to add special case logic to handle "trivial" cases of the ha…

> He just told you. Because the only way to prevent it in general is to solve the halting problem. I'm aware. I think that I might have misunderstood what the optimization really does.

Grandparent presented this as a "surprising optimization" but I'd argue it's exactly what you'd expect when a compiler sees while(expression) -- he just happened to pick a trivial expression.
Post reply on HN