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

11. Thou shalt try C++ or Rust



I come from low-latency java world (yes, that is a thing) and to be effective in my line of work I had to get a decent understanding of what the OS (linux) does under the hood.

Learning C was a blast and I really enjoy reading and writing C code and studying kernel sources.

C++ on the other hand is a fully matured abomination and I want nothing to do with it. Now you can down-vote me into oblivion.


Indeed, C is a much much simpler language. C++ is a language which can take you a good 10 years to master (and while you do so, your knowledge becomes partly outdated)...

On the other hand, you enjoy your C until you find yourself:

* In macro hell to get something complex done

* With overly long functions and function name prefixes.

* Needing to write something serious and big - requiring libraries of all sorts, and noticing they mostly don't exist.

* Wanting to tell the compiler optimizer things that C can't tell it.

* Needing to compute some things at compile-time.

... and then you start developing a taste for the "abomination".


* In macro hell to get something complex done

IMO, macro hell is something you bring upon yourself. I rarely felt the need to abuse the preprocessor in awful ways in order to build something.

* With overly long functions and function name prefixes.

I'm puzzled how you can get in such a situation. Running out of function namespace? How?

* Needing to write something serious and big - requiring libraries of all sorts, and noticing they mostly don't exist.

There are plenty serious and big projects in C and there are _plenty_ of libraries. Also, C++ can be linked with C, so... I fail to see how you don't get the same kind of issues with C++ if there are any.

* Wanting to tell the compiler optimizer things that C can't tell it.

This might be indeed a problem, but... what can you tell it using C++ to the compiler optimizer? I'm not really a C++ guy so, really, do you have more options? I know there are compiler specific pragmas an modifiers in C as well, but does C++ have specific C++ language stuff and not C++ compiler stuff it can set?

* Needing to compute some things at compile-time.

Again... what yould those things be? CRC's? You can do that in C if the compiler allows you as well (gcc and clang do). What else? And what more exactly does C++ bring to the table concerning this?

Honestly, I have to think reaaaal long an hard about things that the C lang doesn't let you do or constrains you. It's one of the most liberating languages, honestly. I work with it day in and day out, so I might be biased, say what you want about C, but not that it's not powerful!


> what can you tell it using C++ to the compiler optimizer? I'm not really a C++ guy so, really, do you have more options?

Yes, in several ways, including:

* Move semantics - you can make the compiler aware that some values are "going away" soon and can be cannibalized rather than conserved. * Compile-time execution - a significant (and growing) subset of the language can simply be computed at compile-time rather than run-time. So if you have a certain function which computes something - anything that doesn't involve I/O (and until C++20 - uses a fixed amount of memory), and your inputs are known in advance, the function won't have to run whenever you run the program, but would be removed entirely in favor of the result.

To see how these and other language features combine to allow for highly-efficient code, check out this video:

CppCon 2016: Jason Turner “Rich Code for Tiny Computers: A Simple Commodore 64 Game in C++17” https://www.youtube.com/watch?v=zBkNBP00wJE

Where you write an implementation of the Pong game - with high-level, straightforward code, and no "dirty tricks" - whose compilation result requires exactly 0 stack and 0 heap space.


Some of that capability is there only to overcome optimization problems that were created by C++ features. You don't need to make the compiler aware that some values are "going away" soon if that is clearly obvious. Without layer upon layer of object obfuscation, optimization is a much easier problem.

In C too, functions are removed entirely in favor of the results. This is a quality-of-implementation issue. There are good and bad compilers for most languages. C is less dependent on compiler quality however, with relatively simple compilers being able to produce good output for stylistically typical code.


I really love C, although I'm no expert by any means. C++ and Rust (and D) are different kinds of languages, they have many many more features. There isn't an adequate replacement yet. Aside from having GC, if anyone mentions Go, yes the syntax is simple but the runtime is a massive magic black box, I don't like magic. The closest things that I can see are Zig or the yet unknown language that Drew Devault is working on[0]. So people know about Zig of course, but the reason I mention about Drew's language that he has hinted at with snippets is that I can see by his posts that he both loves and respects C and he cares about complexity[1], I really really look forward to seeing what he's been up to.

[0]. https://drewdevault.com/2020/04/15/Status-update.html [1]. https://drewdevault.com/2020/01/04/Slow.html


> There isn't an adequate replacement yet.

D as Better C works very well as a replacement. I've converted a lot of code from old C to BetterC and it goes very quickly (once you remove the use of the preprocessor, which can be tricky if you use the preprocessor as a metaprogramming tool). The syntax is nearly identical.

https://dlang.org/blog/2017/08/23/d-as-a-better-c/

Note that no D runtime library is required. Just the C Standard Library.

(Yes, I am in charge of the D Language Foundation. No, I don't receive a nickel from it. I do it because I believe in it.)


Actually yes I did forget about BetterC and it has been on my radar for a while. I have played with D before and honestly out of all the options in this space I've found it's probably the one I would go for on a project. It seems to strike the best balance between productivity and performance for me, the runtime seems much less magical than Go. I will definitely check out BetterC!


The biggest feature of C is its ABI stability guarantees. Swift is one of the few languages that has tried to retain that.


How does C provide ABI stability? If I send someone .o and .a files, I don’t think they can just use them in the general case.


C does not provide ABI stability itself as a language, however the language does make it easier for libraries (including specific implementations of the standard library) to provide ABI stability.

Rust does not provide the facilities to write libraries with stable ABIs, and C++ libraries have to be written carefully to achieve ABI stability. More precisely, important C++ and Rust language features (templates and generics, respectively) conflict with the ability of providing ABI stability (at least it was thought so... Swift is novel in how it provides ABI stability guarantees for library writers alongside generics).


I wonder if anyone's ever tried something like "C with slices, destructors, and copy/move semantics".


Of course. Just use C++ and set some linter rules to enforce disabling other C++ features.


That plus "avoid pure virtual classes", "no use of the heap", "C standard library and header-only libraries only", "compile with no exceptions" gets you close to embedded C++. Except also with classes.


Is this something you would recommend to newcommers? I wouldn't. I can agree that on technical level such subset has a decent set of features and gets the job done. On the other hand when learning how to use this subset, you'll still come across stack overflow answers and other C++ materials that will contradict such methodology, and other coworkers will occasionally challenge that particular stack of choices with their own favourite C++ features. You still have to learn how exceptions work and why avoid them, what is heap and how to disable it, what are pure virtual classes and so on.

I dislike the argument that C++ is great because you can limit yourself to appropriate subset. It becomes a different thing while still being called C++, which is miscommunication. If you can brand your subset as EmbeddedC++ and gain widespread audience, then we're closer to good thing. (except there's lot of embedded happening on Linux boards where "normal" C++ is acceptable)

My frustration mostly comes from working on huge embedded C++ project where each separate corner of codebase used its own subset of language. This brings down complexity and reduces mental overhead locally, but reasoning about the whole system is impossible.


I would much rather recommend something like "C with bounds-checked arrays" than a form of "standard" C++ to newcomers. Yes, StackOverflow will not help much, but I think avoiding the huge amount of features that the rest of C++ brings is well worth it. You are probably not advocating for dumping everything at once onto a beginner, so why not pick a subset that is both really small and gets you quite far?

> You still have to learn how exceptions work and why avoid them, what is heap and how to disable it, what are pure virtual classes and so on.

Do you mean later on? As I see it, you do not have to learn about the things you do not use and can concentrate on the basics. Once you are comfortable and need to venture out into projects where other parts of C++ are used, you would need to, of course.


Yeah I think our views are mostly aligned.

I was pointing out that if you as beginner manage to set correct boundaries for C++, you still need to know what's on the other side in order to avoid it. You've constrained yourself to smaller language (a good thing), but you haven't eliminated all the baggage / mental overhead that rest of C++ brings. The optimal approach would be to pick a language that's already well suited to problem. I would always choose enhanced C over degraded C++.


Yeah, I certainly agree that the features cost you even if you do not use them.


Yes, that is basically "C++ with some certain libraries and the discipline - or static analysis enforcement - to only use part of the features."


That's basically modern C++, if you cut out all the things that aren't slices, destructors, and copy/move semantics.


I believe D has most if not all of those. There is even an official subset of the D language called “better C”.


DasBetterC does indeed have slices, destructors, copy semantics and some move semantics. There's a proposal in the works to add complete move semantics.


Neither of them have stable ABI's




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

Search: