3 ms·
First, stop saying C/C++. If you are talking about C, you are not talking about C++. If you are talking about C++, you are not talking about C. Second, give up
by ncmncm 4y ago
First, stop saying C/C++. If you are talking about C, you are not talking about C++. If you are talking about C++, you are not talking about C.
Second, give up on C. It simply has not got the resources to help you with safety. It is a wholly lost cause.
In C++, you can package semantics in libraries in ways hard to misuse accidentally. In effect, your library provides the safety that Rust reserves to its compiler. C++ offers more power to the library writer than Rust offers. Use it!
- redox99 4y ago> First, stop saying C/C++. If you are talking about C, you are not talking about C++. If you are talking about C++, you are not talking about C. I don't understand why people hate the "C/C++" term so much. C++ is (almost) a superset of C, you can mostly drop C code onto your C++ compiler and it will work. So for OP question, C/C++ implies that he is using a C++ compiler, and an answer using C code would work perfectly fine with his C++ project (it might not be idiomatic C++, but in the world of C++ everybody does things their on way anyway).
- shric 4y ago> C++ is (almost) a superset of C, you can mostly drop C code onto your C++ compiler and it will work. The devil is in the details. The "almost" and "mostly" parts are really important here, especially given that the entire topic is safety. If you compile "C code" with your C++ compiler (as C++), you're no longer compiling C code; you're now compiling C++ code that looks like C. It would be fine if C code, when compiled as C++ had one of two outcomes: 1. Behaved identically to C code compiled as C. 2. Refused to compile Unfortunately, there are things that exist in both languages but have different semantics such as the type of character literals, e.g. 'a' (int in C, char in C++). As for the superset thing, there's been quite significant divergence especially since C99 (e.g. variable length arrays) Other subtly different things include: the bool type (C++ has a bool type, C99 has _Bool with a macro for bool as bool isn't a reserved word in C). designated initializers (C99 had them first then C++20 introduced them to C++ but with more restrictions)
- jstimpfle 4y agoThe things you mention are true but wholly besides the point. C/C++ normally means "C flavoured C++, or just C, I don't care", or it can mean "more modern C++, maybe do a bit of plain C or interface with C libraries". It's more about the domain you're working in and the general approach (compiled language, caring about performance, ....), and results, than about the minutiae of the language you're using. It doesn't mean thinking of C/C++ as literally a language that you can compile, and doesn't mean compiling random C code as C++.
- ncmncm 4y agoNone of that matters. There are plenty of other differences, and they also don't matter. What does matter is that, while you probably can compile your C code with a C++ compiler with minimal changes, it is very bad code. It might be the best C code ever, but as C++, it is just crappy. I mean that technically: the C++ code you could have written instead would have been much, much better. As C++, that C code is just embarrassing. This is not a reason to avoid switching your project over to building with a C++ compiler, which you could do in an hour or a day. Gcc did this, and Gdb, both with rousing success: Gcc and Gdb are now better programs, and you can tell that just using them. Yes, after the switch, all the code will have instantly become bad code. But the secret is, it was always bad code. It was just (one hopes) the best anybody could have done in C. Now you can begin to make it into good C++ code. Incrementally, a little at a time. Probably starting with new features, and some key infrastructure, always resolving immediate frustrations. Each bit makes your program better. Probably most of it will still look a lot like C, forever. That is the code you don't touch much, and haven't needed to. Where you get the real benefit is in places you already have reasons to change. Those are likely to be near where future changes will be, too. There is never any confusion, looking at an evolving project, about which parts are C, which parts are in (say) 2000s-era C++, and which are modern. So, there is no value in trying to stay "consistent". New code is different because it can be. Old code is different because it still is. Some of it will change, and come to look modern, too. Most won't. And that is OK. Keeping code consistent would mean not applying things you have learned, and not doing things better than you could have before. Inconsistent code indicates learning and growth.
- redox99 4y ago
- duped 4y agoWhile I've seen predominantly C codebases that look vaguely like C++, I don't think I've ever seen a C++ (even "C with classes") codebase look like C. In practice people don't drop C into a C++ compiler. They wrap C APIs in C++ classes and move on, or more likely inherit a C++ wrapper around C Libs (and debugging, file i/o, logging, networking, guis, etc) that look nothing like C.
- jstimpfle 4y agoDepends how pedantic you are with your "looks like C" judgement, but in my perception many hardcore programmers write "C flavoured C++, not modern or template-heavy C++" by their own account. John Carmack is only the last whom I've heard say this, just yesterday in the new Lex Fridman Podcast episode.
- ncmncm 4y ago"Not template-heavy" mainly just means not library code. Templates, like most important C++ features, are mainly there to enable writing better, faster, more powerful, and less easily misused libraries than you could have, without. Failing to use good libraries would be a mistake. A library is probably faster and less buggy than what you would code in place. Time spent improving libraries is amortized across all uses, so there is more of it. This is very evident in heavily used libraries. You might not notice the templates much, but they made your experience using the library better. They have tailored the generated code to be optimal for just the way you are using it, instead of doing what would be just OK for all uses.
- jstimpfle 4y agoIt can also mean not overusing libraries, not overabstracting prematurely, seeing if you can simplify the high-level design of the program to not rely on complicated compile time magic so much. There's probably a good balance to using templates where they improve QoL but there's only very little code with those mess of < and > that tend to produce unreadable error messages. But a lot of "modern" C++ I find browsing on the internet way overuses templates IMO. I could be considered a masochist for still writing plain C, but I find it very convenient just having one compiled (not optimized to death) version of code that is parameterized with runtime parameters (mostly sizes, sometimes alignments, rarely function pointers) in most cases. I find it also better for modularity if the library and container code is type-agnostic. It also builds faster, often much faster. Doesn't work for non-POD C++ classes, of course. C-Pointers are often all the "generics" I need, sparing me to type out almost all of the repetitive size calculations. And even that (array access) gets rare as the projects grows more and more structure.