Live data from Hacker News

Getting Past C

blog.ntpsec.org

301–310 of 504 posts

Re: Getting Past C

#301

Earlier quoted context omitted.

Thanks for elaborating on this! > copying bytes if the underlying type has the `Copy` trait and calling some actual code if not, It does not. Moves and copies are both "memcopy these bytes", the only difference is if you can use the previous copy or not. (This is also, of course, subject to the optimizer, which may elide the copy.) > either way some constructor of the object must be called if it exists (though it mig…

Interesting. How does Rust handle types that want to do interesting things when copied, like bookkeeping or updating internal pointers? Maybe you just can't, which would preclude some kinds of intrusive data structures, or owning non-copyable mutexes for example. Does `drop()` get called on objects that have been copied from?

You pretty much just can't; that's what Manish was referencing above about this kind of thing being awkward.

It would be cool to have those things, but it also means that there's less "magic" stuff going on, which is nice. And it makes the semantics of stuff like this a lot simpler.

> Does `drop()` get called on objects that have been copied from?

Nope. In fact, Copy types can't have a Drop at all, but types that move don't have their Drop impl called when they move.

Re: Getting Past C

#302

Earlier quoted context omitted.

CompSci keeps making them, even open-sourcing some, but little uptake or improvements from the FOSS crowd. Here's two of the top ones: http://sva.cs.illinois.edu/ https://github.com/jtcriswell/safecode-llvm37 https://www.cs.rutgers.edu/~santosh.nagarakatte/softbound/

As we've discussed, one issue is the big performance cost of these solutions. Anyone interested in working on an automatic C to SaferCPlusPlus[1] translator? It should address the performance issue[2]. And should be much more straightforward than these C to Rust/Go translators. [1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus [2] https://github.com/duneroadrunner/SaferCPlusPlus-BenchmarksG...

I thought you have an interesting solution to improving safety of C++ code. So, your techniques work with C code done in the old and new C styles w/ no work? Just fire and forget translation of C code written in arbitrary styles to to be completely memory-safe?

Re: Getting Past C

#303

Earlier quoted context omitted.

Interesting. How does Rust handle types that want to do interesting things when copied, like bookkeeping or updating internal pointers? Maybe you just can't, which would preclude some kinds of intrusive data structures, or owning non-copyable mutexes for example. Does `drop()` get called on objects that have been copied from?

You pretty much just can't; that's what Manish was referencing above about this kind of thing being awkward. It would be cool to have those things, but it also means that there's less "magic" stuff going on, which is nice. And it makes the semantics of stuff like this a lot simpler. > Does `drop()` get called on objects that have been copied from? Nope. In fact, Copy types can't have a Drop at all, but types that mov…

Thanks for all the responses, I'm learning a lot. This explains to me why iterators and other references to the internals of a data type have to take ownership of the whole data type, which is something I ran into several times during my (brief) explorations with Rust.

Re: Getting Past C

#304
post #295

Earlier quoted context omitted.

I would be interested in the specifics of the spaces thing (knowing more about ones tools is good) but "10 minutes" to handle all the various issues and bugs that will inevitably pop up from wrangling macros?

Yeah 10 minutes is quite a bit off, at least for me. The various issues and bugs that arose all came about when developing the data structures themselves - they didn't crop up in actual usage. Though my approach was to use a separate header and source file for each new data type I parameterised them by. So I had an "int_array.c" and an "int_array.h". And inside the header would just be function declarations generated…

That approach of a single invocation was what I would personally assume would be done (or put it in the header that defines the data type, for a custom one), but I'm not sure how that solves spaces?

Re: Getting Past C

#305
post #280

Earlier quoted context omitted.

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

How many chip and SoC vendors provide a Rust toolchain? In the case of C, the answer is basically "about as many as provide a toolchain".

Re: Getting Past C

#306

Earlier quoted context omitted.

If you never allocate, there's nothing stopping the compiler from optimizing the GC out. Then you get your first property back, in the sense you originally gave. My point is that Bjarne Stroustrup wasn't comparing against writing the exact same program the exact same way. He was comparing against what you'd get if you dropped down to ye olde C or Assembly and wrote the same algorithm there, without redundant work or…

> there's nothing stopping the compiler from optimizing the GC out. I don't know of a single language that comes with a GC that does this, do you? > He was comparing against what you'd get if you dropped down to ye olde C or Assembly and wrote the same algorithm there, without redundant work or waste. Right. I agree with this. But basically, we are arguing over an extremely fine semantic, which is "should you even wa…

I'm not arguing about whether bounds checks are good, but about whether it's correct to call them zero-cost in the canonical sense. Doing so just devalues the term, and IMO feels like misdirection.

To put it another way, let's say I was a C++ developer on the fence about Rust. If I read this conversation, I'd see that indexing gets called "zero-cost" despite the overhead. Since tons of things in Rust are "zero-cost", like traits, closures, borrowing, etc., all of those things now have doubt cast on them. How can I really trust that these things are actually getting compiled efficiently?

If instead the conversation pointed out that this was one of a few cases where safety took priority over truly being zero cost, but that there were tools in place to mitigate the cost (iterators, unsafe indexing, LLVM), I'd have a much more positive outlook that focussed on what Rust did right.

Re: Getting Past C

#307

Earlier quoted context omitted.

> there's nothing stopping the compiler from optimizing the GC out. I don't know of a single language that comes with a GC that does this, do you? > He was comparing against what you'd get if you dropped down to ye olde C or Assembly and wrote the same algorithm there, without redundant work or waste. Right. I agree with this. But basically, we are arguing over an extremely fine semantic, which is "should you even wa…

I'm not arguing about whether bounds checks are good , but about whether it's correct to call them zero-cost in the canonical sense. Doing so just devalues the term, and IMO feels like misdirection. To put it another way, let's say I was a C++ developer on the fence about Rust. If I read this conversation, I'd see that indexing gets called "zero-cost" despite the overhead. Since tons of things in Rust are "zero-cost"…

I would suspect that a C++ programmer would be more familiar with that actual definition I mentioned originally, and so would understand the subtleties here.

That said, I can appreciate focusing on other things when talking about the principle; I only brought them up here because we were literally discussing them. I think there's much better examples when actually attemping to convince someone.

Re: Getting Past C

#308

Earlier quoted context omitted.

You pretty much just can't; that's what Manish was referencing above about this kind of thing being awkward. It would be cool to have those things, but it also means that there's less "magic" stuff going on, which is nice. And it makes the semantics of stuff like this a lot simpler. > Does `drop()` get called on objects that have been copied from? Nope. In fact, Copy types can't have a Drop at all, but types that mov…

Thanks for all the responses, I'm learning a lot. This explains to me why iterators and other references to the internals of a data type have to take ownership of the whole data type, which is something I ran into several times during my (brief) explorations with Rust.

Totally. There's one other interesting subtlety you might find interesting here, and that's self-referenceing structs. So for example,

struct Foo { s1: String, s2: &str, }

where s2 is always intended to point at s1's backing storage. What's unfortunate here is that Rust will disallow this, as it doesn't understand that s2 is pointing to some data on the heap, with a stable address, not the parts of the String struct in s1 that are part of the struct itself. So what this means is, in plain Rust, this type isn't movable, Rust is concerned about the invalidation.

However, you can get around this restriction with some unsafe code to teach Rust about it; this is the premise of the "owning-ref" crate.

Re: Getting Past C

#309
I like go, I'd love to write libraries in it but as far as I can tell you can't really create a C compatible shared library from it. That it still the common denominator if you want to call into it from other languages. I'd love to write Python programs with performance critical stuff in Go

Re: Getting Past C

#310

Earlier quoted context omitted.

I mean, in case of an abort the kernel generally cleans things up for you :) Not all things, but most things. More exotic panics (like an infinite loop panic on a microcontroller) would not call destructors though. Most panic impls will either unwind (which will call destructors) or abort/exit, so this is usually not a problem.

I'm speaking mostly in terms of recoverable errors where it jumps to a logging section, carries on, but leaks memory.

You'd generally use Result for recoverable errors (which won't have any destructor issues), but in some cases you might put a panic::recover at the event loop level (never seen this being done before, but I can imagine it happening) which catches the panic (only calling destructors up to the catch point -- this is done by the unwind mechanism) and moving on to the next event in the loop.
Post reply on HN