News for hackers. Stuff that matters.
Re:Why undefined behavior may call a never-called function by XCSme on Sunday September 24, 2017 @11:39AM (#15325083)
Very interesting, to me seems like a "compiler bug". The compiler should not automatically set the static pointer value if the function that sets it is never called.

Anyway, I guess "undefined behavior" is really undefined and it means anything can happen, so as per specs it's not a bug. Ultimately it's the programmer's mistake for having undefined behavior in his code.

Re:Why undefined behavior may call a never-called function by electrograv on Sunday September 24, 2017 @11:45AM (#15325108)
Unfortunately, "it's not a bug, it's a feature!" -- there are long-standing design choices in C/C++ where various circumstances are explicitly designed to yield "undefined" behavior where literally anything goes. I believe the original intent of these are to give the compiler/optimizer more room to speed up the executable.

Edit: The 'undefined' clause here is due to invoking a function at address 0, rather than any lack of variable initialization (since global variables are automatically initialized to 0, as the poster below points out).

Re:Why undefined behavior may call a never-called function by mikeash on Sunday September 24, 2017 @11:49AM (#15325130)
Globals are always initialized. If no initial value is specified, they’re initialized to zero.

What’s undefined here is calling a function pointer that contains zero. Thus the compiler assumes that it must have been set before being called, and since there’s only one value it could possibly be set to, it must be that value.

Re:Why undefined behavior may call a never-called function by lisper on Sunday September 24, 2017 @02:20PM (#15325807)
It is a bug, but it's a bug in the spec. Saying that a common mistake like dereferencing the null pointer is undefined and therefore your program can do anything is not useful behavior. The only sane design is for any attempt to dereference the null pointer to cause the program to signal an error somehow. Exactly how that happens can be left unspecified, but that it must happen cannot be unspecified in a sane design. I don't see how any reasonable person could possibly dispute this.
Re:Why undefined behavior may call a never-called function by jcranmer on Sunday September 24, 2017 @03:39PM (#15326146)
> Exactly how that happens can be left unspecified, but that it must happen cannot be unspecified in a sane design. I don't see how any reasonable person could possibly dispute this.

Your proposal is basically tantamount to saying that the compiler can never ever delete any read or write to memory that is unused if it can't prove that the memory pointer is non-null (for example, the pointer is an argument to the function--clearly a very common case).

Trying to formally specify what can and can't be done with common undefined cases (like dereferencing memory that results in a trap or reading uninitialized values) turns out to run into issues where the specification unintentionally precludes common optimizations, and it's not always clear how to word semantics in such a way to not do that.

Re:Why undefined behavior may call a never-called function by lisper on Sunday September 24, 2017 @06:13PM (#15326772)
> Your proposal is basically tantamount to saying that the compiler can never ever delete any read or write to memory that is unused if it can't prove that the memory pointer is non-null

That's right. I would much prefer to take a small performance hit if I might be dereferencing a null pointer than to literally have anything at all happen in that case. If I really need that last little bit of performance I really do want my compiler to insist that my code be correct before it will give it to me rather than take a wild guess at what I really meant to do and get it wrong.

Re:Why undefined behavior may call a never-called function by richardwhiuk on Sunday September 24, 2017 @06:23PM (#15326804)
How big a performance hit? Double run time? Triple? 10x?
Re:Why undefined behavior may call a never-called function by lisper on Sunday September 24, 2017 @07:01PM (#15326981)
I will take any performance hit over the potential for catastrophic failure by default.
Re:Why undefined behavior may call a never-called function by umanwizard on Sunday September 24, 2017 @07:13PM (#15327024)
Then there is an easy solution: compile with -O0. What's the problem with optimizations being available for those who want them?
Re:Why undefined behavior may call a never-called function by lisper on Sunday September 24, 2017 @08:08PM (#15327200)
There is absolutely no problem with optimizations being available. The problem is that the standard gives the compiler license to muck with the semantics of the program in highly non-intuitive and potentially dangerous ways, and this is true regardless of what flags are passed to the compiler. So I can't depend on anything working even if I specify -O0, at least not by the standard. I am entirely at the mercy of the benevolence of my compiler vendor.

If the compiler is going to be given license to make those kinds of dangerous non-intuitive changes to the program semantics I want that to be evident in the source code. For example, I would like to have to say something like YOU_MAY_ASSUME(NOTNULL(X)) before the compiler can assume that X is a pointer that can be dereferenced without signaling an error if it's null. That way the optimizations are still available, but it is easy to tell by looking at the source code if the author prioritized speed over safety and if there are potential gotchas hiding in the code as a result. The way it is now, the potential gotchas are like hidden land mines, nearly impossible to see, and ready to blow you to bits (pun intended :-) without warning.

Re:Why undefined behavior may call a never-called function by jcranmer on Sunday September 24, 2017 @10:23PM (#15327675)
> So I can't depend on anything working even if I specify -O0, at least not by the standard. I am entirely at the mercy of the benevolence of my compiler vendor.

What you're basically saying is that you want semantics that's basically defined by the compiler vendor (or, more accurately, compiler/operating system/hardware trio), but you're pissed that the standard leaves it up to the compiler vendor as to whether or not you will get that option. You're already "at the mercy of the benevolence of [your] compiler vendor" to give you things like uint32_t, why is the presence of a -O0 inherently worse?

Re:Why undefined behavior may call a never-called function by lisper on Monday September 25, 2017 @02:47AM (#15328500)
No, uint32_t has been part of the C standard library since C99.
Re:Why undefined behavior may call a never-called function by electrograv on Tuesday September 26, 2017 @10:55AM (#15339188)
Yeah, I completely agree that this behavior is not sane. It is designed behavior, perhaps designed so with good intentions, but foolish assumption nonetheless (that the “undefined” behaviors would be predictable if left truly undefined).

So yeah, I’m pretty happy to call this a “design bug” in the entire language. Those kinds of bugs are hard to fix, because you need the whole C++ committee to fix this, and we all know how bad design-by-committee performs.

So just switch to Rust :)

Re:Why undefined behavior may call a never-called function by ramshorns on Sunday September 24, 2017 @04:57PM (#15326461)
Well, strictly speaking, it's a bug in the example program. If it were fixed to not invoke undefined behaviour, then this unpredictable thing wouldn't happen.
Re:Why undefined behavior may call a never-called function by lisper on Sunday September 24, 2017 @06:06PM (#15326740)
It's (probably) true that it's a bug in the program, but the sane behavior would be for the program to signal an error resulting from an attempt to dereference the null pointer.
Re:Why undefined behavior may call a never-called function by eridius on Sunday September 24, 2017 @03:26PM (#15326088)
How do you know it's never called? You can call the function from another file. It's not possible to know that the function is never called until link time.
Re:Why undefined behavior may call a never-called function by gmueckl on Sunday September 24, 2017 @05:47PM (#15326653)
No, the function pointer is declared static. It cannot be referred to outside the current file.
Re:Why undefined behavior may call a never-called function by DSrcl on Sunday September 24, 2017 @06:33PM (#15326846)
The function pointer is static. But the function that mutates it, NeverCalled, is not. One can still indirectly change that function pointer.
Re:Why undefined behavior may call a never-called function by cesarb on Monday September 25, 2017 @08:17AM (#15329763)
> The compiler should not automatically set the static pointer value if the function that sets it is never called.

It doesn't automatically set the pointer value. It only assumes, when reading the pointer, that it can only be NULL or EraseAll (NULL is the initial value, EraseAll is the value set by NeverCalled, since the pointer is visible only to the same C file there are no other possibilities). Then it sees a function call through the pointer, and assumes it cannot be NULL (you can't dereference a NULL pointer, much less call through it). The only value left is EraseAll; since that's the only possibility, it is inlined at the call site. At no moment was the static pointer value modified.