Live data from Hacker News

Getting Past C

blog.ntpsec.org

391–400 of 504 posts

Re: Getting Past C

#391
post #161

Earlier quoted context omitted.

So you want the array to have type foo * ? Ignoring that this doesn't let the compiler help the programmer with arrays (you still have to manually remember to use the accessor, not []), you also have to manually remember which pointers are pointers and which are arrays, and this representation doesn't work for pointing into subsections of an array (a similar problem to C-style strings), nor does it work well for putt…

agree -- inability to do variable-sized arrays on the stack is the root of the problem.

What do you mean? Variable-length arrays are OK in C.

Re: Getting Past C

#392

Earlier quoted context omitted.

> 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 s…

> I work on a C codebase that does this […]. 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) […]. This is a complex, >1M SLOC distributed system that has seen several years of production use at this point […].

>

> […] it just needs to be done from the start, and then you just need a bit of discipline to keep it up.

Here's a neat idea: wouldn't it be cool and save a lot of time if the compiler did this for you automatically, from the start?

Of course, you say it's easy to do it manually, but something tells you your company might have needed to pay less for development if the compiler did it automatically with no human intervention required.

Re: Getting Past C

#393
post #257

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 actually a very helpful comment. I used to think "zero-cost" meant "at compile-time", as in `newtype` in Haskell, etc. I'm guessing that's what the parent commenter thought as well, and I'd guess is what most people think when they hear the phrase.

Well, you can still sort of view it that way. You can imagine the bounds check being a "compile time generation of the C code you'd write to check the bounds anyway".

Re: Getting Past C

#394
post #161
post #140

Earlier quoted context omitted.

No, you just allocate enough space to store an extra int at the start for the length, and return a typed pointer to the actual data. Then you need an accessor that checks bounds, if you want safe access. Both of these problems are solved by simple macros.

So you want the array to have type foo * ? Ignoring that this doesn't let the compiler help the programmer with arrays (you still have to manually remember to use the accessor, not []), you also have to manually remember which pointers are pointers and which are arrays, and this representation doesn't work for pointing into subsections of an array (a similar problem to C-style strings), nor does it work well for putt…

I agree that having to remember is a problem, it's one of the many shortcomings of C that it doesn't let you differentiate between types at compile time.

Pointing into subsections works fine. You just have to create a type for it. This solution doesn't have the same problems as strings because you don't rely on a terminating entry, and it's what languages like Rust or Java do as well.

You can allocate dynamic arrays on the stack in C just fine with alloca(). The only performance cost is when checking bounds, but since it's a dynamic array, it's the same cost you'd pay in Rust.

Re: Getting Past C

#395

I wish more mention of D would happen. It is compatible with C and C++ libraries and features GC without sacrificing the good things of C and C++. I always loved the idea of Rust and Go but they are nowhere near C or C++ where it matters to me. D fits the bill, otherwise I just use Python. I like being able to design software in my own way as opposed to being told how to do it.

Same thing with Ada. If you're looking for a safer low-level language with a long track record of successful use by some major players, Ada is the natural first candidate.

But as someone else said, Rust has had way better marketing (and is newer, which probably catches some people as well.)

Re: Getting Past C

#396

I didn't understand why rust and go are natural alternatives to C. Wouldn't C++ be a more natural option? (Despite the fact that both go and rust are developed by third party companies)

C++ would be a great alternative, assuming the developer(s?) working on the project didn't hate it, as is the tradition: http://esr.ibiblio.org/?p=532

Oh well, at least they're moving from C, which will be a big win either way.

Re: Getting Past C

#397
Why do they have to use a low level language ? Why not use NodeJS ? One argument would be time management, but even with C you can not be sure that no interrupts happens in between ...

Re: Getting Past C

#398

Earlier quoted context omitted.

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 an…

There is no need for another unsafe fast language. There is also no need for another safe slow language. We already have enough of those. Rust's purpose is to find a middle ground between those extremes.

Re: Getting Past C

#399

Earlier quoted context omitted.

> i just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up when trying to work with memory in Rust. False. Buffer overflows in C can overwrite the program's memory, so it can be hijacked and supplanted with the attacker's code. This cannot happen in Rust (unless unsafe code has the vulnerability), or any memory safe language. Sure you can implement a safe array…

How much does that still happen with DEP and such? Don't OSes not let you write to executable regions or execute from stack/heap by default now?

You don't need to execute the stack. Just use ROP to fill the stack with return addresses that point to "gadgets". Gadgets are basically a single assembly instruction at the end of a function like XOR EAX,EAX and then a RET. Every time a RET is executed the CPU will jump to the next gadget. There are usually enough gadgets inside a program to basically do anything you want.

https://www.exploit-db.com/docs/28479.pdf

Re: Getting Past C

#400

Earlier quoted context omitted.

C unions have no discriminant. But yeah it's a pity—I'd try to hack up discriminated unions then. Or convert to Rust unions and then enums and remove unsafety.

C union declarations should correspond pretty closely to rust enum declarations. It's a surprisingly important feature. Every large codebase I've worked on has clunky workarounds for storing heterogeneous types in collections. Haven't seen a silver bullet; dynamic languages are great at this until you have to scale (either in lines of code, number of types or dataset size) and then they become unmanageable. Static la…

At least that one is really simple in Crystal:

  x = [] of Int32 | Char
  x 
=> [42, 'F']
Post reply on HN