Live data from Hacker News

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

kukuruku.co

91–100 of 189 posts

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

#91

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.

[deleted]

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

#92

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.

The idea (I assume) is to let compilers optimize away loops without determining that they terminate. I.e. the rule is more aimed at loops which would terminate, but this lets compilers avoid proving that they do in fact terminate.

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

#93

Earlier quoted context omitted.

Exactly. You are assuming that a poorly written standard is correct and engineering practice of working programs is incorrect.

Ok, so you want compilers to generate a translation for program #2 that works "correctly" to your mind when x is null. Please explain to the class the meaning of the construct int y = *x; when x is null, so that all conforming C compilers can be updated to generate code for this case "correctly".

Something like

    assert(x);
    int y = *x;
is probably closer to the intended meaning. Checking if(!x) afterwards is still dead code, but at least the program is guaranteed to fail in a defined manner.

Of course, if implemented this way, every dereference would have to be paired with an assert call, bringing the performance down to the level of Java. (While bringing the memory safety up to the level of Java.)

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

#94
post #93

Earlier quoted context omitted.

Ok, so you want compilers to generate a translation for program #2 that works "correctly" to your mind when x is null. Please explain to the class the meaning of the construct int y = *x; when x is null, so that all conforming C compilers can be updated to generate code for this case "correctly".

Something like assert(x); int y = *x; is probably closer to the intended meaning. Checking if(!x) afterwards is still dead code, but at least the program is guaranteed to fail in a defined manner. Of course, if implemented this way, every dereference would have to be paired with an assert call, bringing the performance down to the level of Java. (While bringing the memory safety up to the level of Java.)

That's the opposite of what he wants. He wants a compiler that produces a translation which derefrences the null and follows the true branch.

He wants null to equal a valid addressable address, which is completely nonstandard and not portable to everywhere C is used, to be standard that portable compilers emit code for.

He wants to imagine that null and zero are the same thing.

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

#95

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.

[deleted]

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

#96

Honestly, Optimizing compilers will kill C. It killed the one thing C was good at - simplicity (you know exactly what happens where, note I'm not saying speed, as C++ can be quite a bit faster than C). Now, due to language lawyering, you can't just know C and your CPU, you have to know your compiler (and every iteration of it!). And if you slip somewhere, your security checks blow up ( http://blog.regehr.org/archives…

If you do know your compiler and your CPU (singular), you're probably not really programming C. Conversely, if you maintain software that compiles on a bunch of compilers, operating systems and architectures (particularly little endian + big endian, 32 bit + 64 bit), then it's probably written in something rather like C. A lot of people do this.

> If you do know your compiler and your CPU (singular), you're probably not really programming C.

The point is that C is still cleaner than assembly for long programs.

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

#97

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.

Speed isn't the only reason to use C. I often use C not because it's fast, but because C is by far the simplest mainstream programming language. All these UB warts notwithstanding, no language's interface comes as close as C's to a basic, no-frills register machine.

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

#98
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…

It means that empty loops (loops with empty bodies) can be completely removed if the controlling expression has no side effects. > This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven. It means while(i) {} can be eliminated as if i were 0, because there are no side effects in the loop expression or the loop body, and what would be the point of the lo…

> If you really want to go to sleep, use pause() or similar. An infinite loop eats up CPU cycles

Yes but an infinite loop + sleep is okay, right?

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

#99
post #77

Earlier quoted context omitted.

You're thinking about it in the context of actual computers. The C standard says absolutely nothing about what NULL has to be, besides that the integer value 0 is considered to be the NULL address and that dereferencing it is considered invalid. The NULL address does not have to be all 0 bits. Architectures are generally free to define it to any invalid address they want to be NULL, 0 just happens to be a common and…

>The catch you're pointing out is that on x86 there are technically no 'invalid' addresses Depending on what you mean precisely by "x86," there is such a thing as an invalid address: the IA32e architecture (or whatever you want to call Intel's flavour of 64-bit "x86") requires that the high bits of an address match, where is machine-dependent.

That's a fair point - though I think you could debate whether or not the current 48-bit address space of x86-64 is part of the architecture or just an implementation detail. But in the end I don't really think it matters which you consider it (And I'd be happy to consider it to be either). All that said, you're completely right that with current x86-64, there are 64-bit values that could never be a valid address.
Post reply on HN