5 ms·
Re: [mongrel2] C versus C++ (2010)
- hdevalence 13y ago> You'll find crap in C++ like const *const char &, and hell if anyone knows what that really means since even though the pointer to a const to a const reference is consted to hell and back, oh look you can still increment it. They'd have been better off to just invent a new keyword: doesnotfuckingchange and stop there. As I recall, Stoustrup originally wanted to call the const keyword 'readonly', which is a more accurate description of what it does (const data is not constant, it's read-only: something else can change it while you're not looking, but you can't change it). They didn't, for compatibility reasons with C. That said, the const keyword allows you to move contracts about, e.g., "this method does not alter its object", from the programmer's head into the code where it can be checked by the compiler. (unless you have people doing stupid things with mutable or const_cast). But yeah, C++ has flaws. Big flaws [1]. Anyone who tells you otherwise is probably uninformed or lying. The interesting question is, why do people keep using it in spite of its flaws? Certainly a large part of that is inertia, but I don't think that that's the only thing. I think there's a niche where there's really not a lot of good options other than C++, and that's quite unfortunate. But "C++ sucks" removes the possibility that there's anything useful there, making discussion of better alternatives (e.g., would D work? what is it about C++ that makes it useful? how do these languages compare? etc.) impossible. See, for example, Rob Pike's complaint about why C++ programmers aren't all moving to Go, which essentially ignores a bunch of reasons why you might use C++ (since Go is not a replacement for them). See [2], [3]. [1]: http://bartoszmilewski.com/2013/09/19/edward-chands/ http://bartoszmilewski.com/2013/09/19/edward-chands/ "I’ve been looking for a good analogy of what programming in C++ feels like and I remembered this 1990 Tim Burton movie, Edward Scissorhands." [2]: http://blog.grok.se/2013/10/on-comparing-languages-c-and-go/ http://blog.grok.se/2013/10/on-comparing-languages-c-and-go/ [3]: http://commandcenter.blogspot.se/2012/06/less-is-exponentially-more.html http://commandcenter.blogspot.se/2012/06/less-is-exponential...
- catnaroek 13y ago> But yeah, C++ has flaws. Stroustrup dixit: "Within C++, there is a much smaller and cleaner language struggling to get out." Rust? > The interesting question is, why do people keep using it in spite of its flaws? Certainly a large part of that is inertia, but I don't think that that's the only thing. Ownership management. Which has been expanded into full lifetime management (including that of borrowed pointers) in... Rust! Static polymorphism. Which is implemented in a crappy way in C++, but at least is doable: 1. Non-specialized templates: Type constructors. 2. Concepts (sadly only in the heads of programmers): Type classes. 3. Exported typedefs and type traits: Type families. > See, for example, Rob Pike's complaint about why C++ programmers aren't all moving to Go, which essentially ignores a bunch of reasons why you might use C++ (since Go is not a replacement for them). Dude must be completely deluded.
- hdevalence 13y agoYeah, Rust is really interesting, and something I'd like to try on a real project. Hopefully I'll be able to do something with it this spring. But it's certainly more appealing as a replacement than, say, Go, which I don't think is really even that interesting as a language (but this is a personal opinion which I'm not willing to argue about on the internet). Rust also would immediately solve some things I find particulary annoying about C++ (lack of sum types, inability to create new types that behave identically to old types, etc). One thing that I think would be nice to have in a hypothetical language is vector support for integral types, the same way OpenCL has. The Eigen library for C++ is IMO a really good example of the "Edward C++hands" phenomenon. It's a terrific library, using C++ template magic to produce optimized assembly for your platform, to achieve performance you just can't get with C. On the other hand, it can be annoying to use, since there are places where the C++ warts come out, and the developers have to put in an extraordinary amount of effort just to get there. If you had this kind of thing built into the language, it's much easier for everyone involved: compiler authors, programmers, library developers, etc.
- charlieflowers 13y agoThat's cool. Do any of the new wave of systems programming languages offer this kind of capability? D, Rust, Nimrod, etc.?
- pmelendez 13y ago>" You have to do all the same memory checks, use valgrind, make sure you've got destructors, and then that's made more complex by templates, object lifecycles, exception rules, etc.. Frankly C++ doesn't have better memory management than C, it just has more complex management." I strongly disagree with the author, and I suspect he is biased for the "old school" C++ (as he called it). For instance: >make sure you've got destructors. Objects allocated on the stack are guaranteed to be destroyed and hence their destructors to be called. Which is very convenient if those objects are owners of a resource (like a DB connection). >"and then that's made more complex by templates, object lifecycles, exception rules, etc.." Object lifecycle are well defined but if all is an OOP problem not a C++ one. As for the rest, the beauty of C++ is that if there is something that doesn't apply to your project, then you don't use it. Your are not required to use exceptions or templates if you don't want to. > "Frankly C++ doesn't have better memory management than C, it just has more complex management" Again, if you want to it can be complex, or it can be the same management you would do in C. That's a flexibility that simply you don't have in C.
- eropple 13y agoAgreed. His Boost complaints are odd, too; even in 2010 it certainly didn't take "forever" to build Boost and its templates are for the most part very logical and essentially hidden to you (see for example boost::format, which does pretty much exactly what he says he wants out of a formatter). He's got a point that for mongrel2 the full feature set of C++ doesn't necessarily make sense, but having it available when I want it is really valuable to me. For my game, I literally couldn't do what I'm doing without some really big, really gross crap that would be multiple times the code I have. (Faking polymorphism with state machines makes everyone sad.)
- pmelendez 13y ago>"the full feature set of C++ doesn't necessarily make sense, but having it available when I want it is really valuable to me" Exactly my point. In C++ you have all those tools available and you won't pay for them until you start using them.
- 13y ago
- film42 13y agoThe whole time I was reading this I couldn't help think of all the "ported x to 30 lines of javascript" headlines. By that I mean, just because it can be done in a language, doesn't mean it's the best fit. I think his best point was about dropping in boost. It doesn't make sense to add more code, increase compile times, and complicated stack traces just to use C++. I have to admit, I go out of my way to use newer tech sometimes even though I know it'll slow me down. But, we (I) need to remember something about Software Engineering -- at the bottom line, we're building software. Its language and design should reflect the best possible result, and while that doesn't always mean speed, it does mean using the best tools to solve that problem.
- eropple 13y agoWhen using modern compilers, the overhead for Boost is pretty minor. I get that this was a big deal some time ago (I wasn't using C++ then, so I can't say myself) but using Boost with clang and precompiled headers don't cause a significant increase in compile times except in the case of a clean, which is rare enough for me that I just use that as a chance to get up, move around, etc. Boost can weird your stack traces a little, but they exhibit in predictable ways that you can usually quickly reason out if you understand what your stuff is doing.
- pcloadletter 13y agoImagine C is like giving a wannabe tinkerer a knife; then C++ would be like giving him a knife, blowtorch, dremel. With the C guy, you more or less know what kind of damage he can do, and what kinds of trouble he can get into. So you are able to look out for that. The C++ guy, OTOH has exponentially more ways to cause damage. Basically, both are tools, which, in the hands of a skilled artist, can do wonders. But in the hands of the inexperienced (99%), C++ is a lot more dangerous and complicated.
- catnaroek 13y agoNot really. C++, at least modern C++, is a huge improvement in terms of safety over C. The problem with C++ is that this improvement has been achieved in a clumsy way: instead of providing clearly differentiated means of static abstraction (e.g., non-specializable generics for parametric polymorphism and concepts for ad-hoc polymorphism), we get templates, which have been equipped with all sorts of corner cases (specialization, SFINAE).
- aidenn0 13y agoNote that had mongrel2 been written in c++, I would not be working on it right now. Not because I necessarily think it's bad, but because I don't know hours to write good c++. there are all sorts of tricks to making c++ tractable[1] and I just don't have enough familiarity with them. 1. See for example RAII rule of three, etc.
- JSno 13y agoTo me, I don't care this kinda debate. I just keep improving my C and C++ skills. Whatever language my manager wants to use. I just use it. (I can write Python, Haskell and Java, C# too) My personal favorite one is C though.
- coherentpony 13y agoRight. I don't see why we're having this discussion. You use C++ if you want to deal with higher-level objects. The argument of, "memory management is easier," is a total fallacy, just like has been pointed out in that list message.
- bitwize 13y agoThere is absolutely no reason not to use C++ in modern software development. C++ gives you deterministic object lifetimes without the overhead of manual management through the RAII pattern and smart pointers. It gives you std::string, which is as easy to use, if not easier, than char*. It gives you parameterized types and real value semantics for user-defined types. There are even template versions of strcpy and friends which pass implicit length parameters to strcpy_s and friends, which prevent a whole class of buffer overflow bugs which have been the bane of C programmers since the language came into existence. With all the added safety and convenience that C++ gives you over C, it is literally insane to use C where C++ could be used.
- papaf 13y agoThere is absolutely no reason not to use C++ in modern software development. Its nightmarishly complicated and gives you 1000 ways to blow your foot off, and maybe one or two to get the job done properly. After about 18 years of C++ development I still go for C sometimes. C is a lovely language that is much easier to learn. I cannot believe anyone would cheerlead for C++. Its a necessary evil.
- asveikau 13y agoThere's plenty of reasons to prefer C over C++, but I don't feel like this post is doing a good job of capturing them. I was much more amused by Linus's version: http://lwn.net/Articles/249460/ http://lwn.net/Articles/249460/ IMO the most confused part of this post is to dismiss templates as "stupid". I myself am rather "C-leaning" but I can acknowledge that some C++ features are well thought out. Templates enable a lot of the "good C++" in a number of ways. My favorite example: for things like callbacks and lambdas. In C you often find yourself using function pointers for this. With templates, you can make that a compile-time cost instead of a runtime cost. So your callback can get inlined right inside the caller. One practical result of this: things like std::sort are faster than libc's qsort. Similarly, he is right to say that exceptions can introduce memory leaks in C++... But the C++ advocate's position would be that the RAII pattern avoids this. And when you get into that habit, so long as you are consistent with it, I can't say the whole thing is too bad. It's rather elegant. Personally I think the problem is not C++ itself, rather that it asks a lot of developers to be able to navigate towards the "good C++" and avoid the costly anti-patterns. To make matters worse, people don't agree about what the "good C++" is. IMO this is all more of a social problem than a technical one. Which leads me into something similar to Linus's argument, to choose C to "keep the C++ programmers out" -- not that it's impossible to do C++ well, but that there's a large community of people who are "doing it wrong", even if you can agree what "right" is.
- ridiculous_fish 13y agoI and my colleague ported a mature project (the fish shell) from C to C++, over a period of about a year, so our experiences are relevant. Like many projects, fish uses C++ as mainly a better C, without embracing exotic templates, exceptions, smart pointers, boost, or other high-powered features. Most of Zed’s points do not apply to this style of programming, and anyone considering a port to C++ ought to consider it. C++ as a better C does impose some costs, such as longer compile times, more cryptic error messages, nastier backtraces, and losing compatibility with some older systems. But these are tolerable, and on balance the benefits are worth it. In one case, fish strayed and used shared_ptr, which caused compatibility pain. This suggests we’ve hit a sweet spot, where if we adopted more C++ features we’d start to see a greatly increased cost. Just using std::string would reduce the mm noise and make the code easier to read and reduce the chances of memory leaks. This is indeed what we found. The memory management simplification was a huge deal, and that drove my decision for the port. However, the big win came not from the specifics of C++'s memory management, but from its regularization: imposing a single memory management scheme. Like most C projects, the shell was rife with char . When you see a char , you can't immediately know who owns the string, who is responsible for deallocating it, and how it should be deallocated. std::string lets you reason locally about the code, but so too do C libraries such as GObject, CFString, etc. C++ won out over these alternatives because it's more widely supported and has a deep pool of potential contributors. But the C++ "feature" that mattered most was not that its memory management scheme was better, but that it existed. C is really the best because it is the lowest friction access to all the POSIX stuff you need This is a big concern that disqualifies most other languages. For example, Go or Haskell cannot easily do checks like `#ifdef VDSUSP`, and have no guaranteed semantics for threads after fork. C is undisputed king here! But C++ doesn’t impose much additional friction as long as you stick to the POSIX primitives. e.g. pthread_* instead of std::thread or std::lock. There is no “huge bother.” The semantics of destructors are incredibly confusing, especially with exceptions. Destructors are indeed terrifying when in the direct gaze of a fully operational C++ battlestation. However they are simpler in a suitably sane subset of C++. The fish shell, for its part, disallows all exceptions, even compiling with -fno-exceptions for a binary size savings. No matter what, unless the language has a GC built-in, then C will have simpler and more predictable memory usage. As I argued above, the important aspect here is not the choice of language, but the choice of memory management scheme. It is possible to make memory management simple and predictable, or instead ad-hoc and haphazard, in both C and C++. The key difference is that C++ comes with a scheme built-in (which you may or may not choose to use), while C does not. I don’t know how mongrel manages memory, but the “no matter what” claim is obviously wrong. I couldn't imagine trying to use the string output stream stuff to craft messages and things. Indeed: wstringstream is a big memory hog! But choosing C++ does not commit you to using the stream formatting syntax, nor does it preclude using printf-style formatting. fish uses printf-style formatting everywhere. On the flip side, the simple task of appending two strings is awkward in C. Either you have a fixed size buffer, or you commit to some string object type, which then requires manual copying and cleanup. C++’s strings have flaws, but they definitely simplify string handling compared to C. Even something as simple as casting a float to an int is a pain in the ass involving some weird template like syntax that frankly makes no sense. C++ typecasts are mainly designed to support exotic template usage, and they are indeed weird and onerous when using C++ as a better C (my pet example is `static_cast<size_t>(-1)`). C++ programmers also promote the C++ casts as “safer” or “better”, and characterize the C-style casts as “unsafe” and “legacy.” Score one for Zed. Leaving it off here, but I hope I showed how Zed’s points apply to using C++ in all its glory, and that “C++ as a better C” is totally viable for portable, POSIX-using software.