Live data from Hacker News

Getting Past C

blog.ntpsec.org

271–280 of 504 posts

Re: Getting Past C

#271

Earlier quoted context omitted.

Considering that a change in language completely solves the problem, it's hard to get on board with your thesis.

My point is, a lot of people are spending time on this when it doesn't matter. In the limit that AI starts replacing human developers these subtle differences in language approaches zero. New languages here and there every day. Replace this replace that. When, in the end everyone is simply reinventing the "wheel" over-and-over. All these languages end up as assembly.

This sounds a lot like "why clean up my room when the heat death of the universe is coming anyway?", but if you do think that AI is going to supplant all of programming then be the change you want to see in the world! Get building and we'll see which one happens first.

I honestly don't know who I'd put my money on between "AI takes over the world" and "programmers stop writing buffer overflows"

Re: Getting Past C

#272

Earlier quoted context omitted.

Neither C nor C++ knows, at the language level, the size of an array, unless that size is fixed. The subscript checking variants of C and C++ have to use "fat pointers" which carry along size information. The overhead for this is large and nobody uses that. Fat pointers used to be a feature you could turn on in gcc, but it's somewhat abandoned now.

> Neither C nor C++ knows, at the language level, the size of an array, unless that size is fixed. Neither does Rust. > The subscript checking variants of C and C++ have to use "fat pointers" which carry along size information. So do Rust's Slices. > The overhead for this is large and nobody uses that. People use std::vector all the time for this purpose in C++. It has about the performance you'd expect, with very li…

One thing that I've heard might be a difference, but haven't confirmed yet: Rust's lack of move constructors. So you have a vector, it's full, you push one more. It has to reallocate. How do you copy all of the elements over to the new allocation? In Rust, it's a straight memcpy of T * n bytes. But due to move constructors in C++, IIRC they must be moved one at a time.

Again, I haven't actually dug into this; maybe someone more knowledgeable about this can point me in the right direction here?

Re: Getting Past C

#273

Earlier quoted context omitted.

>if people really want zero cost abstraction That one "if" is (by definition) not zero-cost.

It is by definition a "zero-cost abstraction." Let's ask Stroustrup, who coined the term: > C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better. Two points: What you don't use, you don't pay for: if you don't use array indexing, you won't get a bounds check. In addition, you can call an access method without a bou…

This is a misrepresentation of his comment. By your interpretation, you could call GC zero-cost!

Most code doesn't use bounds checking, because the branch is a safety net you should never hit, even in theory. Any code that does hit it is already broken. Correct programs using bounds checked indexing will in general be slower than but equivalent to a program where indexing instead results in undefined behaviour.

Re: Getting Past C

#274

Honestly, why not do it once and for all in a strongly typed pure functional language, validate it, and then tweak the GC parameters to get the performance? Use the safest and most powerful language that you can, if you can.

> strongly typed pure functional language > tweak the GC parameters to get the performance Care to give an example of such a language which allows for a guaranteed GC pause\resume configuration\declaration\etc in a critical section?

F# (i.e. the CLR) has this, although it's not pure:

https://msdn.microsoft.com/en-us/library/system.gc.trystartn...

Re: Getting Past C

#275
post #27

Can anybody make a strong case to me as to why are buffer overflows considered an issue in C when it takes like 10 minutes to write and test an array implementation that prevents that from ever happening? I do agree that C has issues (though in my opinion neighter Rust nor Go address almost any of them) i just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up w…

Obviously, one can program C to do anything, and write all the provably safe abstractions wished. But, that's not really the point. The point is that doing such is not the default. It requires engagement and knowledge of the programmer, especially on distributed projects with loose communication, such as many open source projects. And it only takes one programmer mistake to bring the whole house of cards down. Why al…

Why allow programmers to make mistakes?

For a philosophical counterpoint: Why allow anyone to do anything that might possibly be incorrect, harmful, or otherwise perceived by some to be negative?

I've looked at a lot of the talk surrounding "safe/secure languages", "safe/secure programming", etc., and yet every time I've heard people preach about the benefits, I feel like I just vehemently disagree. At a very deep and fundamental level, I feel like somehow we are sacrificing something more important in the pursuit of this "safety", this seemingly overpowering desire to make everything completely safe, mindlessly constricted, and stifling. It's not just software; the whole "war on terrorism" irks me in the same way. I imagine a "completely safe" world, the ones these "safe software" proponents appear to be striving for, would be rather dystopian.

A quote that immediately comes to mind is: "Freedom is not worth having if it does not include the freedom to make mistakes."

Re: Getting Past C

#276

Earlier quoted context omitted.

"out of C into a language with no buffer overruns, and in general much stronger security and correctness guarantees." Doesn't sound like C++.

I still don't get it. Can't it be done in c++ via appropriate data structures? I mean, it's not like Go is magic, at the end I suppose Go would be doing just that. As far as I know the main reason people opt for Go over C++ are the compiling times...

You can write safe C++, if you're careful, and everyone you work with is careful, all the time. Judicious use of features can make your code more safe, but they can never make it actually safe.

Rust and Go, in various different ways (and to various degrees), make it actually safe.

Re: Getting Past C

#277

Earlier quoted context omitted.

Hate to tell you, but JavaScript implementations virtually all rely on C or C++ as well. And it's not limited to the VM itself: check out npm "native extensions" like `json`. Not to mention glibc, or the OSes themselves. By your definition, nothing is safe. And you're right ;)

That's the old "formal proofs are useless because the proof checker might have a bug" argument. It's not very persuasive.

It's MaulingMonkey's argument ad absurdum is what is is :P

Re: Getting Past C

#278
post #27

Can anybody make a strong case to me as to why are buffer overflows considered an issue in C when it takes like 10 minutes to write and test an array implementation that prevents that from ever happening? I do agree that C has issues (though in my opinion neighter Rust nor Go address almost any of them) i just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up w…

> Can anybody make a strong case to me as to why are buffer overflows considered an issue in C when it takes like 10 minutes to write and test an array implementation that prevents that from ever happening? The CVE database. Just because you 'can' write such an array implementation doesn't mean you will, doesn't mean your third party libs will, doesn't mean any of your legacy code uses it, and certainly doesn't mean…

> I ask this in bad faith: I encourage you to share a single nontrivial codebase which actually creates the abstraction you've described and religiously adheres to using it throughout. As to why this is in bad faith: I'm definining "nontrivial" here to mean using 3rd party APIs - which will operate on C style arrays, not your project specific safe wrappers - and thus by definition won't be "religiously" sticking to said abstractions when using said APIs. By these definitions, the codebase I'm asking for doesn't exist - by definition. Even relaxing the "third party" rule, I haven't actually worked on a nontrivial C or C++ codebase without buffer overflow problems.

I work on a C codebase that does this, although in the slightly weaker sense that it does drop the abstractions at a few isolated interaction points with external APIs (think openssl, linux system calls, and not a whole lot else). Yes, there is quite a lot of NIH. With essentially-uniform use of checked data structures, and an extremely comprehensive suite of automated tests getting run under ASAN (originally Valgrind), memory safety errors almost never get so far as being committed to the main branch. This is a complex, >1M SLOC distributed system that has seen several years of production use at this point, and as far as I can recall we have not seen a single memory safety related issue in production (a few have managed to to get as far as certification testing). General resouce-leak class issues have struck a few times, but are also pretty rare.

Proprietary, naturally, so I can't actually show you (sorry), but it absolutely can be done in practice. It isn't even really all that difficult, it just needs to be done from the start, and then you just need a bit of discipline to keep it up.

Re: Getting Past C

#279

Earlier quoted context omitted.

It is by definition a "zero-cost abstraction." Let's ask Stroustrup, who coined the term: > C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better. Two points: What you don't use, you don't pay for: if you don't use array indexing, you won't get a bounds check. In addition, you can call an access method without a bou…

This is a misrepresentation of his comment. By your interpretation, you could call GC zero-cost! Most code doesn't use bounds checking, because the branch is a safety net you should never hit, even in theory. Any code that does hit it is already broken. Correct programs using bounds checked indexing will in general be slower than but equivalent to a program where indexing instead results in undefined behaviour.

Most GCs would violate the "What you don't use, you don't pay for". That is, they add runtime cost (and "the size of the runtime" size) to code, even code that doesn't allocate.

"You couldn't hand-code any better", well, I won't argue on that point, as it sounds contentious. ;)

_Should_ never hit is very different than will never hit...

Re: Getting Past C

#280
post #52

Earlier quoted context omitted.

And once you have written a five line safewrite() function, a hundred-line saferecvfrom() function, a 1500-line safeioctl() function, and all of that, and you have a third-party static analysis tool to prove that you're never calling the unsafe read() or ioctl() functions except from the wrappers, what was the advantage of staying in C in the first place?

The advantage is that you're depending only on yourself and C. That third party static analysis tool can just be "grep". Or some mild text processing on the output of "nm" to validate that no object files (other than the allowed ones) have external refs to those symbols.

I think it's a massive programming ecosystem blind spot that "depending on c" is seen as less of a burden than depending on rust
Post reply on HN