Live data from Hacker News

Why undefined behavior may call a never-called function

kristerw.blogspot.com

41–50 of 183 posts

Re: Why undefined behavior may call a never-called function

#41
post #36

This is literally a religious argument. No sane person would consider this acceptable behavior if not for the fact that there is a holy text ("the standard") that says it's acceptable. Well, it's not acceptable. It is no more acceptable than, say, a car that explodes if you push the wrong button at the wrong time, which would be clearly unacceptable even if there were a document blessed by a standards committee that…

> You'd think that decades of security breaches caused by buffer overflows would make people think, "You know, it's 2017. Maybe array dereferencing without bounds checks is a bad idea even if it does let my code run a little faster." Alas.

And there are dozens of languages that will let you sacrifice that bit of speed for some safety.

Re: Why undefined behavior may call a never-called function

#42
post #41
post #36

This is literally a religious argument. No sane person would consider this acceptable behavior if not for the fact that there is a holy text ("the standard") that says it's acceptable. Well, it's not acceptable. It is no more acceptable than, say, a car that explodes if you push the wrong button at the wrong time, which would be clearly unacceptable even if there were a document blessed by a standards committee that…

> You'd think that decades of security breaches caused by buffer overflows would make people think, "You know, it's 2017. Maybe array dereferencing without bounds checks is a bad idea even if it does let my code run a little faster." Alas. And there are dozens of languages that will let you sacrifice that bit of speed for some safety.

[deleted]

Re: Why undefined behavior may call a never-called function

#43
post #41
post #36

This is literally a religious argument. No sane person would consider this acceptable behavior if not for the fact that there is a holy text ("the standard") that says it's acceptable. Well, it's not acceptable. It is no more acceptable than, say, a car that explodes if you push the wrong button at the wrong time, which would be clearly unacceptable even if there were a document blessed by a standards committee that…

> You'd think that decades of security breaches caused by buffer overflows would make people think, "You know, it's 2017. Maybe array dereferencing without bounds checks is a bad idea even if it does let my code run a little faster." Alas. And there are dozens of languages that will let you sacrifice that bit of speed for some safety.

If you meant to imply that this is not a problem because there are other languages one can use, I disagree. C holds a unique position in the computing world. There is an enormous corpus of C source code out there, and more is being written all the time notwithstanding that C as currently specified in not a sane language. So what C compilers do matters whether you like it or not.

Re: Why undefined behavior may call a never-called function

#44

I suspect this is another critical point: as NeverCalled may have been called from, for example, a global constructor in another file before main is run clang doesn't analyse across module boundaries --- even when it theoretically could --- so it doesn't know for certain that NeverCalled() is indeed never called. Throughout the years I've grown increasingly displeased at how compilers handle even trivial cases like t…

> Unfortunately, I'm also sure that we don't have the time to do it.

And that really is the crux of the issue. Despite the significant amount of discussion around the problems of C UB, there is precious little work being done to actually "solve" the problems.

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

> Since we published the Friendly C proposal, people have been asking me how it’s going. This post is a long-winded way of saying that I lost faith in my ability to push the work forward. However, I still think it’s a great idea and that there are people besides me who can make it happen.

Re: Why undefined behavior may call a never-called function

#45

If you make one small change to this file you can cause clang and gcc to both prevent this from compiling if you are using warnings. namespace { void NeverCalled() { Do = EraseAll; } } or marking NeverCalled as static itself. Results in warning: unused function NeverCalled. In general this is best practice for functions defined and used in a single translation unit.

That's a vital part of the setup. You could hypothetically link this compilation unit against another unit which included: void NeverCalled(); struct A { A() { NeverCalled(); } }; A a;

You don't even need C++, you can just use C and __attribute__((constructor)).

Re: Why undefined behavior may call a never-called function

#46
post #11

I have become convinced that the current screw-the-programmer interpretation of ‘undefined behaviour’ was not intended, or even imagined, by the original ANSI C committee. Within the committee's mandate to ‘standardize existing practice’, it was simply an acknowledgement that C compilers translated straightforward C code into straightforward machine code without adding safety checks, and that simple code might —​ in…

The original ANSI C committee had no idea about modern optimization pipelines. If people had continually pushed back against undefined behavior back then, there's a good chance that by 2017 the result would have been that C would be dead , replaced by a language that allows for modern optimization techniques.

And would that be such a bad thing?

How come we have languages like Rust that achieve almost the same speed while maintaining dramatically better safety, anyway?

Re: Why undefined behavior may call a never-called function

#47
post #7

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.

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

#48
post #11

I have become convinced that the current screw-the-programmer interpretation of ‘undefined behaviour’ was not intended, or even imagined, by the original ANSI C committee. Within the committee's mandate to ‘standardize existing practice’, it was simply an acknowledgement that C compilers translated straightforward C code into straightforward machine code without adding safety checks, and that simple code might —​ in…

AFAICT, the main rationale for undefined behavior in the original instance boils down to traps: any operation that could trap is undefined. In particular, this seems to motivate why signed integer overflow is undefined as opposed to implementation-defined. It should be pretty clear why it's a good thing that potentially-trapping instructions have undefined semantics in those instances (or, perhaps more accurately, have semantics that have large leeway for when, where, and if the trap is triggered).

Undefined behavior is generally nowhere near as bad in practice as it's often made out to be in practice. It's mostly a case of taking code that is manifestly wrong and making it manifest wrongly in different ways, and when you look at how and why compilers use the undefined behavior to optimize, it's hard to actually object to it. The two main counterexamples are strict aliasing (although it should be noted that most compilers will use the strict aliasing rules only if it failed to figure out aliasing by other means, so trivial things like int_var = (int)&float_var don't end up being deleted as being nonsensical) and signed integer overflow (note that wraparound semantics usually are as equally bad as undefined behavior, but making it be undefined makes it challenging to check if the operation would overflow).

Re: Why undefined behavior may call a never-called function

#49
post #11

I have become convinced that the current screw-the-programmer interpretation of ‘undefined behaviour’ was not intended, or even imagined, by the original ANSI C committee. Within the committee's mandate to ‘standardize existing practice’, it was simply an acknowledgement that C compilers translated straightforward C code into straightforward machine code without adding safety checks, and that simple code might —​ in…

The original ANSI C committee had no idea about modern optimization pipelines. If people had continually pushed back against undefined behavior back then, there's a good chance that by 2017 the result would have been that C would be dead , replaced by a language that allows for modern optimization techniques.

You're the last person I'd have expected to make that sound like a bad thing.

While benchmark games played a part in the modern ‘undefined behavior’, I'm not so sure that it would made much difference to adoption of the language. Consider Linus Torvald's well-known rant as a point in the opposite direction.

In the universe where ‘undefined behaviour’ had been clearly specified as ‘what you write is what you get’, C might have gone to consistent use of optimization-enabling annotations, following ‘const’ (and later ‘restrict’). Along those lines, ‘volatile’ was ANSI's other big mistake, as creating it broke existing code; I now think that should have been the default, with fragile-optimizable status being explicitly indicated by extending the use of ‘register’ keyword.

Re: Why undefined behavior may call a never-called function

#50
post #49

Earlier quoted context omitted.

The original ANSI C committee had no idea about modern optimization pipelines. If people had continually pushed back against undefined behavior back then, there's a good chance that by 2017 the result would have been that C would be dead , replaced by a language that allows for modern optimization techniques.

You're the last person I'd have expected to make that sound like a bad thing. While benchmark games played a part in the modern ‘undefined behavior’, I'm not so sure that it would made much difference to adoption of the language. Consider Linus Torvald's well-known rant as a point in the opposite direction. In the universe where ‘undefined behaviour’ had been clearly specified as ‘what you write is what you get’, C m…

It's not just benchmark games. It's people's real-world code.

Look at how often folks on HN complain that the Web platform is useless because JS is slow. C without optimizations is just as slow if not slower. Compiler optimizations are so good that people don't realize how much they rely on them.

Linus was wrong when he complained about the compiler treating null dereference as undefined behavior. This is a very important optimization, because it allows the compiler to omit a lot of useless code in libraries. Often times, the easiest way to prove that "obviously" dead code can never be executed is to observe that the only way it could be executed is for null to be dereferenced.

Opt-in optimization keywords wouldn't scale to the sheer number of optimizations a modern compiler framework performs. Restrict hasn't been a success because it's too subtle of an invariant. It's the kind of thing compiler authors, not application developers, should be thinking about.

Post reply on HN