Hacker News new | past | comments | ask | show | jobs | submit login

[flagged]



> On a side note, I can't help feeling sorry for the people that advocate for C over C++ when I see commits like https://github.com/wasm3/wasm3/commit/121575febe8aa1b544fbcb...

To be fair, I/O is a place where C++ really dropped the ball, too. The <iostream> part of the C++ library is unfortunately a complete mess. This is not really a “win” for C++ as much as it is a failure for both languages.

I think it is hard to advocate for either C or C++, for greenfield projects, these days.


C++20 improves the situation, though. https://en.cppreference.com/w/cpp/utility/format/format

But yes, in a world where Rust exists, I don't see a need for C or C++ for greenfield.


There are plenty of greenfield use cases where Rust will need to bind to existing C and C++ libraries.


I guess the field I was imagining was greener than that. But yes.

In many cases you can just interface to the C libraries. But cross language coding has never been perfect, and yes, sometimes it's better to continue using the same language.

It's not hard to write an RAII wrapper around a C library, and the careful allocate/free is code you have to write either way (e.g. I'd write a wrapper in C++ if I need to use a C library with resource handling).

C is the easiest to interface with. Every language has to be C-compatible.

I would not choose C or C++ just because I depend on libfftw, or simdjson, or most other things. If the code that needs to talk to the library is less than 10% of the total program (exact percentage just made up), then I'd still use Rust.


So many of the CVEs against rust crates are actually against the bindings for things like ssl, glibc, and libcurl. I think accepting small growing subsets of ssl and curl for native implementation would be a good idea. And relibc too I suppose. Go went this route, and while it caused some headaches porting to new kernels, it has lots of benefits too.


Go has had to rollback on that decision.

Rust while much safer, also needs care if any crate makes use of unsafe, even in pure Rust.

https://thesquareplanet.com/blog/the-story-of-a-rust-bug/

Yes it is in the libc bindings, but the logic error is on Rust side.


That story seems to be about missing code/functionality, more than anything about a vulnerability. There is way more unsafe out there than there should be. Bindings are are one of the very few cases that must have it.


Just use bindings isn't always as easy.

It depends on the company, the team skills, the tools they are used to have, the difference when moving into Rust, eg CUDA in C++ with NSight and Visual Studio plugins from NVidia, versus Rust.


Yup. I feel that I left plenty of space for this use of case in my comment.

But as for team knowledge of C++, that's temporary. In the long run, because of the avoidance of many bugs, it may save time.

But there are also no silver bullets.


I mean you can just not use iostream? A lot of modern C++ projects just ignore it. For either C style IO or more C++ -y IO.


Yeah, but you can equally ignore fgetc and friends in C. My only point here is that IO in the standard library is not very good in either language.

IMO a parser should be reading the entire file, and then parsing as a block of memory, by default, for most use cases these days. That way you don’t have to think about IO while you are parsing. Streaming parsers are niche these days for good reasons.


Don't worry, we enjoy that kind of stuff.

I usually put all the resource freeing at the end of a function under a goto label, or only a few lines within the allocation, so it's easy to visually confirm everything is cleaned up. The way this commit frees the resources inside of if blocks is not how I would have done it. And if I find I let a leak in the code I usually refactor to make the correctness more obvious.

In this example, the fact that m3_ParseModule takes ownership of the wasm pointer is very tricky. It looks like there is still a leak but there is not.


> it's easy to visually confirm everything is cleaned up.

Yes and no.

It's easy to not make a mistake in a function. It's basically impossible to not make this mistake in 1'000 functions.

Especially as code evolves over time, being 99% perfect about this, or even 99.9% perfect, is just not good enough. Not nearly enough.

And this reminds me of something Schneier said, that everyone can make a cryptographic algorithm that they themselves cannot break. That even as a professional, having your algorithm broken is not even embarrassing.

Similarly, very good coders are not even embarrassed when they fail at memory management. People may be better or worse at it, but even the best of us are terrible at it.

I once knew a very good coder who bragged about how apparently he's the only one able to write code that's not buggy like this.

To prove a point, I spent an hour reading his opensource project and found several resource leaks, at least one of which was remotely triggerable.

It's easy to do it right once, usually, but no these mistakes happen all the time.

> if I find [… typo words(?) omitted … ] a leak in the code I usually refactor to make the correctness more obvious.

This seems to contradict that it was easy to avoid in the first place. Yes, refactor can help. But there's a bit of learned helplessness, in that this is actually the language's fault, and it doesn't have to be that way.


  > To prove a point, I spent an hour reading his opensource project
  > and found several resource leaks
Sounds like some interesting case studies. Could you share some?

  > > if I find [… typo words(?) omitted … ] a leak in the code I
  > > usually refactor to make the correctness more obvious.
I should rewrite this as - if I find a leak that I accidentally introduced, I will refactor in the process of correcting it, to make the mistake harder to repeat and the correctness easier to confirm.

There are non-language mechanisms that help code run safely, like Wasm, which is a sandbox. Also msan and asan should be used more.

Thinking that changing the language is the right way to fix all the problems you mentioned still seems like a premature assumption. The fact that 100% perfection is worth pursuing at all costs is theoretical and you could be losing things more valuable in the process - e.g. FFI bindings suck, and the added fragmentation in having so many languages in the craft is a pernicious cost with a multitude of aspects to it.


Can't be more specific without doxing myself, I'm afraid.

There are non language ways to make things safer, sure. Take C++, one can do things other than RAII to avoid resource leaks, and it'll be a good pattern. But RAII is right there.

In C++ one can be disciplined about object ownership. But I find that in Rust "doing the right thing" is not optional.

Static and strong typing have similar virtues.

You can write fine software in assembly. Steve Gibson apparently does.

I'm not saying there are any silver bullets. I do appreciate that five minutes spent now being forced to think about object ownership, can save a six month project down the line refactoring to remove all shared_ptrs.

Not accidentally creating copies, because RVO has many conditionals on when it happens.

No silver bullets. But in my opinion C is always worse than at least a C++ subset deliberately chosen. Plain C is because you enjoy the journey, not because you'll get there faster or better.

In C++ you can refactor to RAII encapsulate, when a resource is leaked. In C you can't.


  > To prove a point, I spent an hour reading his opensource project
  > and found several resource leaks
This is asking a lot, but if you enjoy that, I would be thrilled if you could do the same for some of my C projects - nusort and werm under github.com/matvore.


These days I have less time, and more obligations and side projects than time.

Doesn't hurt to ask, though. :-)


That change is the reason we have (in C#) a code style rule that all blocks must have braces.


It's not about braces, it's about the missing free statement.


In a way I'm surprised the language standard for C hasn't been extended to have a standardized RAII "hook" concept?

I don't think it's that far outside of the core language philosophy. Though it would take years for it to make it through to all toolchains and actually be adopted.


For some people, “invisible” function calls are the devil incarnated and against the alleged C philosophy of “what you see is what you get”.

Arguably a compromise would be that you still have to write the resource-freeing calls explicitly, but the compiler would verify that you didn’t forget them. On the other hand, that’s what linters could already do.


"defer" (1) is probably making it in eventually, but it's not trivial.

(1) https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2895.htm





Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: