> “For reliable software, you need Garbage Collection”
> “For efficiency, you must write low-level code”
> “C++ is for large, complicated, programs only”
Well, 2.5/5 of those aren't myths. You certainly don't need to write low-level code for efficiency, C++ does a rather poor job of acting like an OO language, and you don't need Garbage Collection, you just need to not manage memory manually, for which solutions other than GCs exist.
You don't have to learn all of C to write C++, but unfortunately you have to learn C to understand other people's C++, because other people will not restrict themselves to the subset of C++ you consider respectable. That's true both for the C bits of C++ and for the obscenely complex corners of C++.
And C++ isn't just for large, complicated programs; it's for small, complicated programs too.
"And C++ isn't just for large, complicated programs; it's for small, complicated programs too."
hahahahahahaha!!!!!!!!!!!!!!!!!!! -- I was thinking that, but hadn't put it into those exact words yet.
I was thinking something like "C++ is definitely for complicated programs" -- not that they necessarily need to be complicated, but that C++ often unnecessarily complicates them.
I really wanted to like the STL a long time ago, but I gave up eventually. Happily my frustration with C++ led me to investigate other programming languages (not that it was the only one I had used), and I write precious little in it lately -- mostly just to modify code others have written in it.
I want to explain why you are getting down-voted: Hacker News don't like onomatopoeias like “hahahahahahaha!!!!!!!!!!!!!!!!!!!”. In general, a neutral tone is preferred and tongue-in-cheek is acceptable (like parent).
This is an important difference with most subreddits (some, like /r/AskHistorian have a similar ambiance); it avoids ending up with long, heated and shallow conversations.
I'm not exactly new here. I figured some might not like the "hahaha...", but I don't really care. That's exactly what I did when I read the parent comment.
I didn't just leave it at the onomatopoeia -- I made a very reasonable comment afterwards.
>"I was thinking something like "C++ is definitely for complicated programs"
I am not sure which language are you comparing it to but there is definitely a subset of C++ that is easy to use, very readable and type safe.
My only problem with C++ is somebody else code, because there is also a terrible subset of C++ where things can turn very hairy. But same can be said about C, and actually C sometimes encourage you to be "clever".
Yes, and I am fully aware of reasonable subsets of C++.
However, there are multiple other languages that I would rather program in -- although there are still places where I would chose to use C or C++.
I was mostly disappointed that when I tried to use many of the features of C++ that were beyond an intermediate level, the real warts of the language made it not worth the hassle.
I suspect some of that has improved in the latest version of the language spec (and some in the version prior), but I haven't seen anything so far that has excited me enough to get back into it much.
In 1995 C++ it wasn't a good choice. In 2000 it was a poor decision in most cases. In 2005 it was a bad decision in almost every case. In 2010 it was completely indefensible. It is almost 2015, why are we even talking about it? C++ was a mistake. A bad detour on the highway of computing.
"C++ sucks" has become a bit of a meme around here. The upsides outweigh the downsides for a surprising number of cases. Every alternative is either immature, doesn't solve the use case that needs C++ or doesn't have the required libraries/tools.
There are people that sit back and bash C++ and then there are people that just roll up their sleeves and build really cool things with it. I'd certainly rather be in the second camp. I wouldn't mind having a simpler, more elegant language with the same design tradeoffs but that language doesn't yet exist.
Nobody I know. People I know that use C++ every day will admit it has issues but are also realistic enough to understand that any language with the same design constraints and long history as C++ will be complex.
It's the catbirds in the gallery that don't actually have to write the kind of apps that require a language like C++ that "bash" it.
This is my point exactly. I'd consider both git and the Linux kernel tough projects, so the choice of the programming language is interesting. More so, given his stance on C++.
How come it's interesting ? Linus has always been a C -programmer, and kernel space is something where you want to keep things simple and access tha raw bits of things, so C is a natural choice.
And if you've been programming C for 20 years or more, writing git with C feels like a natural solution.
It's not always about writing stuff with the most high definition solution, it's more about expressing ideas with the tools you know also.
> I've come to the conclusion that any programmer that would prefer the project to be in C++ over C is likely a programmer that I really would prefer to piss off, so that he doesn't come and screw up any project I'm involved with.
Quintessential Linus, but I wouldn't call this an "evaluation"... :)
But for projects that don't view those design constraints as very important and projects created when there were other languages that don't have the same history those compromises/explanations won't help. If/when there is a better language you don't have to suffer the history of C++ anymore, just use a newer language without the history. And if the constraints for example were to make it C compatible and very fast, for many projects those may not be of much importance anymore. Other language may be fast enough and easier to write in. I think it is probable that most of todays applications has lower speed requirements than C++ were aiming for. Those who needs speed can probably still use C.
My experience with legacy C++: Main problem with C++ is that it has lots of accidental complexity and a relatively weak standard feature set. The lava layer pattern is apparently very hard avoid in old applications. Due to the aforementioned weaknesses the lava layering now applies also to the modules that would be standard static modules in other languages. So it's a bit wastefull.
But since lava layering is caused by cultural and architectural issues I cannot claim that the system would be in any better shape just if some other language had been used.
>Do you really think C is any easier to understand that C++?
Yes. C is very small and simple. You can learn all of C in a very short time. C++ is the most complex programming language in existence. It is unlikely that there is any person in the world who actually knows it all, including the creators.
>or you could try to implement or use an existing implementation of a dynamic array
Imagine that. You could use libraries that implement things you want. What a concept.
> "Imagine that. You could use libraries that implement things you want. What a concept."
I think I didn't explain myself, but something that basic in these days should be on the standard library in my opinion.
>"Yes. C is very small and simple. You can learn all of C in a very short time."
I don't think C is simple at all. Its syntax can be really cumbersome at times (see my first example). Also it is very annoying to debug, and C code is very prone to contain memory corruption bugs and leaks.
C has great advantages but being simple is not one of them.
>I think I didn't explain myself, but something that basic in these days should be on the standard library in my opinion.
Ok well you hop in your delorian and go back to 1970 and let them know. In the mean time, how does that in any way make C not capable for the same tasks as C++?
>I don't think C is simple at all
Then you don't know C. The entire point of C is that it is simple.
>Its syntax can be really cumbersome at times
That has nothing to do with simplicity, and C++ has far more complex syntax.
>Also it is very annoying to debug
C is very simple and straight forward to debug. C++ is much more difficult to debug. Have you ever used either language?
>and C code is very prone to contain memory corruption bugs and leaks.
Because it is so simple.
>C has great advantages but being simple is not one of them.
Well your opinion is in the vast minority, and does not seem to have any basis in reality. The C spec is a tiny fraction of the size of the C++ spec.
>Ok well you hop in your delorian and go back to 1970 and let them know.
Well they could have added in C99 or more recently in C11. What's wrong about updating a language?
> In the mean time, how does that in any way make C not capable for the same tasks as C++?
I would rather prefer not reinventing the wheel and a language that actually ship with it.
> Then you don't know C. The entire point of C is that it is simple.
I know C fairly well to recognize it quirks (just like all languages have). I think your definition of simple is very different of mine. Scheme is simple, InteractiveC is simple, C it is not.
> That has nothing to do with simplicity, and C++ has far more complex syntax.
cumbersome(adj): difficult because of extent or complexity
simple(adj): 1.easily understood or done; presenting no difficulty. antonyms: complex
How come something cumbersome has nothing to do with simplicity?
Also I am not saying that C++ is simple. But it has a subset that it is well defined, type safe and easy to understand.
> C is very simple and straight forward to debug. C++ is much more difficult to debug. Have you ever used either language?
Yes, I have used both in my formal job, and I can avoid memory leaks and memory corruption easily on C++. Not the case on C, specially when working in medium size teams where always people forget what they should cast a void* into and why they should not.
>>and C code is very prone to contain memory corruption bugs and leaks.
>Because it is so simple.
Seriously? It is a feature now? Well Scheme is a good example of language that is order of magnitudes simpler than C and it is not prone to memory leaks nor memory corruptions
>"Well your opinion is in the vast minority, and does not seem to have any basis in reality. The C spec is a tiny fraction of the size of the C++ spec."
If by simple you mean simpler than C++, yeah. You could say the same of Perl. Does is it make Perl a simple language?
Nothing, they do update the language. But fundamentally changing the language to be completely different is not the same as adding some small thing. C is simple on purpose. Adding complexity is not just an update, it is making it no longer suitable for its intended goal. So they choose not to.
>I would rather prefer not reinventing the wheel and a language that actually ship with it.
You don't have to reinvent the wheel, use a library like you already said.
>I think your definition of simple is very different of mine
Clearly. But mine is the same as 90% of the people who have commented on the subject. People overwhelmingly describe C as simple.
>Scheme is simple
Yes it is. As is C.
>How come something cumbersome has nothing to do with simplicity?
You just quoted how. Are you joking?
>Also I am not saying that C++ is simple
But you are arguing that C is complex and thus not appropriate, while C++ is appropriate. You can't have it both ways.
>Yes, I have used both in my formal job, and I can avoid memory leaks and memory corruption easily on C++
Which has what to do with debugging? And why are you incapable of avoiding those problems easily with C when everyone else does it just fine?
>Not the case on C, specially when working in medium size teams where always people forget what they should cast a void* into and why they should not.
Yes, clearly there's no way groups of people could work together on large complex software in C. I'll go tell linux, apache, X, all 4 BSDs, nginx, postgresql, postfix, etc, etc, etc that they don't exist. I'm sure they'll be glad to know.
>Well Scheme is a good example of language that is order of magnitudes simpler than C and it is not prone to memory leaks nor memory corruptions
Scheme is not even one order of magnitude simpler than C. Go read the specs. And scheme is not prone to memory leaks and "corruption" because it is higher level. This also makes it much slower. Even more importantly, it makes it a ridiculous comparison.
>If by simple you mean simpler than C++, yeah.
You are the one advocating C++ over C while claiming C is too complex. What are you blaming me for?
>"In 1995 C++ it wasn't a good choice. In 2000 it was a poor decision in most cases. In 2005 it was a bad decision in almost every case. "
Was it? Most console games are written in C++ in that period of time. A very popular desktop office suite is built on C++. The most popular design and photograph edition tool for Windows is written using C++.
So you are suggesting that all those guys who picked C++ for those popular piece of software are a sort of lucky morons?
It is a strong and risky assertion don't you think?
I wasn't writing games in 1995 but I suspect you are mistaken. Fortunately https://en.wikipedia.org/wiki/1995_in_video_gaming tells us about the major games that year; unfortunately there are 33 of them. Descent and Mortal Kombat 3 are the ones I remember. https://github.com/drguildo/Descent/blob/master/MAIN/AUTOMAP... Descent is written in C++ (note the "//" comments) but it's a very C-styled C++, not even with classes. MK3 I don't have any idea, but it was eventually released for a lot of platforms with different CPUs, so I doubt it was written in assembly.
>Descent is written in C++ (note the "//" comments) but it's a very C-styled C++, not even with classes
That is C. Lots of C compilers supported // comments, like watcom which they used. Notice the file extension says it is C. Notice it uses absolutely no C++ features at all.
http://en.wikipedia.org/wiki/RollerCoaster_Tycoon
Still using ASM in 1999. Go look at quake 3 which was when id started into C++. Notice how it is barely C++. It seems odd to "suspect I am mistaken" rather than look at the evidence which lines up exactly with what I said.
Thanks for helping me look at the evidence! Maybe you're right. Do you want to pick another two or three random games from that list and figure out what language they're written in? Or figure out what MK3 was written in? I was trying but then I ran out of time while writing my comment.
I don't think RollerCoaster Tycoon is a good piece of evidence because it's famous largely for being written in assembly at a time when most games had already abandoned it.
(Sadly, I don't think it would be odd at all to ignore the evidence, but I aspire to better than that.)
I am not sure about 1995. But at least since 1998 exists Unreal engine and the amount of games using it is humongous. And Unreal's source code is more involved that just C with Classes. (Which by the way is still C++)
The original unreal in 1998 was C with classes. And a significant amount of asm. And note that was in 1998, and part of the sales pitch was that it was OO, which was essentially unheard of at the time. C++ compilers were still really bad at the time, and if you wanted to be portable you really couldn't use much besides C with classes. The unreal engine has been rewritten from scratch several times over the years. What we have now is not indicative of what we had 15 years ago.
It's unfortunate that you were downvoted when you're right, at least for the console space. You couldn't use many of the advanced features of C++ on the consoles of 1995 (rtti, exceptions, STL was garbage in 1995); C++ compilers were all non-conforming and so cross-platform was horrible; code optimization was bad and space/cpu was at a premium. I don't think either the Saturn or the PS1 devkits even had a C++ compiler in 1995 though it would have been possible, and the other consoles definitely didn't. I think people get used to how well things work and how ubiquitous tech is now and they don't remember how it used to be.
There are still a lot of problem areas where GC is unacceptable, or you need precise control over memory, or access to things like Cuda, along with the high order programming constructs you get in C++.
C++ is currently really the only choice if you're making an application that is both large and performance critical. If you're building a AAA video game or a web browser or a robot's navigation system then it probably is the best choice even if it's a painful one.
That is technically undefined behavior, because the result of the double subtraction could very well be a number that is not representable within the range of a signed int.
">" does not form a total order on doubles if you include NaN, so that's not really suprising. That is, you're providing a comparison function which is invalid, you should (at best) expect invalid results.
This is one thing I wish C++ advocates would stop bringing up. While it's technically true that the page count of the C++ spec is comparable to that of C# and Java, not all pages are created equal. The C++ spec is incredibly dense, it's written in a very terse style and often packs as much information into a single sentence as other specs spend an entire paragraph on. Also, the Java spec in particular is typeset with much larger margins, a larger font, and generally more vertical white space than the C++ spec making it seem relatively bigger than it really is.
Not to mention, the spec of Java has the benefit of being built on very firm semantics, regardless of how well they were designed. C++ has no such solid footing on which to stand.
I think the biggest problem is that many idioms in C++ can only be understood by those of us that embraced the language since the C++ARM days and understand the design decisions to built the language on top of the C toolchain.
C++11 and C++17 might be quite a pleasure to use when a small team controls all the code, unfortunately most of the real world applications are done in pre-C++98 style.
And then, you still need to learn about each libraries use which version of the standard.
This is why there are so many fundamental types like string duplicated everywhere. We had to rely on third party libraries like Tools.h++ for consistency across compilers and OSs, before the majority reached C++98 compliance.
qsort only requires one invocation of the comparator to determine the order, while std::sort often requires two. So qsort ought to be faster when comparisons are expensive.
qsort wins by 2x with clang++ on OS X, 10x with g++-4.9 on OS X, and by about 14% with gcc 4.8 on Linux.
This may be a pathological case for either implementation, since the array is already sorted. Still the point about std::sort requiring up to twice as many comparisons is valid.
1.) std::sort doesn't require twice as many comparisons
2.) You not only have a vector with equal items, you have a vector of the same item repeated. That removes all data cache issues which I think is generally unrealistic and unfair.
3.) An already sorted vector is not only pathological, it's something that you usually need to optimize for (probably both qsort and std::sort are bad choices)
Neat! That said, std::sort is a template function, so you can pull the source (e.g., take the one from libc++) and change the comparator to return an int. You will still get all the benefits of inlining and optimizations from lack of type erasure, while performing only one comparison :)
Edit: Actually quicksort only needs a stable boolean comparator (e.g., < or >) to determine order. So the number of invocations to the comparator is the same for both qsort and std::sort. Source: http://en.wikipedia.org/wiki/Quicksort
I'm not sure why std::sort should require two comparisons. It's not required to be stable (neither is qsort), so when comparing a and b gives (a >= b), std::sort can just assume (a > b) and the array will be sorted just fine.
What Bjarne doesn't mention is the enormous difference in code size between qsort and std::sort. The flexibility of having the compiler generate a sorting routine from std::sort is convenient but enormously redundant in many cases. In LLVM, we have array_pod_sort which is just a thin wrapper around qsort in order to avoid the code bloat of std::sort: http://llvm.org/docs/doxygen/html/namespacellvm.html#ae5788f...
For example, the following generates about 2KB of instructions (and will for basically every new type you want to sort):
A qsort equivalent will only emit code for the comparator which is just a handful of instructions.
C++ templates may be type safe and all, but at the end of the day they spew duplicated code just as much as those header-only macro-based C containers and algorithms; really more because it's less painful to write templates (vs. macros) and so you do it more, and there is more stuff in the templates. So even though in general the specialized generated code might be faster in most cases (as Bjarne likes to tout), the overall hit on your code size (and i-cache) can be dreadful. Currently, avoiding this issue in C++ just requires diligence on the part of the coder (some optimizations like LLVM's mergefunc can help, but in general it is a pretty hard problem and compilers are not Sufficiently Smart (TM) yet).
As long as std::sort can fit in the instruction cache, who cares? (outside the embedded world obviously) It will always be faster unless you're getting regular instruction cache misses.
Even if each instance of std::sort fits in the instruction cache, it's helping to push some other code elsewhere in the program out of the instruction cache, slowing that code down in the process.
If std::sort pushes something out of icache, it's to make room for inlining swaps and compares. I'm skeptical that the other things bumped from icache should be kept hotter.
In addition to the "unless you sort 10 elements" factor, as stated in a sibling comment -
LLVM + libclang together are already 46MB of code, and they're libraries designed to be statically linked. Sure, they aren't going to fill your drive, but they will take a comparative while to load from disk (especially as part of another application - doesn't matter much on the command line), and it's that much harder to justify including them in an otherwise small downloaded package.
Your concern is valid, especially since it includes measurements on a real project. But I'm not sure it's a major concern. One can (and you already do) use qsort when binary sizes become a concern.
This is an interesting optimization, but it's not suitable for a beginner-to-intermediate C++ audience, which is who Stroupstrup is addressing. The sensible default is to use std::sort.
If someone can (and it looks like you have) measure a benefit in doing something special, then she should have at it. If an entire project, again with measurements, can prove that std::sort shouldn't be its default sort algorithm, that's fine too.
Does C++ not deduplicate templates that work on the same size types? E.g. if I used std::sort on arrays of `int`, `unsigned`, `float`, and half a dozen structs of exactly 4 bytes, I don't see why there would need to be more than one copy of the template in the final binary.
One of the reasons people use "low level code" for performance is because the STL doesn't easily provide control of memory which is critical to performance. Electronic Arts wrote their own version of the STL largely so they could better control memory [1].
I'm not really sure about the rest of the myths. I'm a little confused about how "To understand C++, you must first learn C” is a myth since C++ is a superset of C so you kind of have to learn C.
I guess that depends on your definition of 'easily' - you can provide custom allocator s fairly easily. What's more problematic are things like the memory usage patterns of std::vector and std::string. Once you know how they work you can avoid the pitfalls or use custom alternatives.
Things like alignment support didn't come out in g++ until 4.8 [1] but now you could start actually do most of what the EASTL is doing aside from the access to private members
There's an example in Part 1, where string concatenation is used as an example. C++ requires "adding" two string objects and C requires manipulating char pointers. And thus, C++ is a better teaching programming language.
Although true, I feel this argument is rather weak: it's true, that when teaching I wouldn't want to start with pointers and malloc's from the get go, but it does not mean C++ is the only alternative.
If you're teaching systems programming, don't hide pointers. In this case, knowing the addition operator is useful iff they understand the underlying operations.... chances are, if they're learning C++, they don't.
Then don't use C++. There's a tool for every need. I wouldn't use C++ either if there was an option for cross-platform, high performance, non-garbage collected way to program highly interactive VR -applications. There simply isn't, so I must use C++ and learn it.
But got to say, my experiences with learning C++11 has changed how I view C++, it's much more robust and nice environment than what I thought, the new C++11 and C++14 really bring some nice things to the table.
I agree, that C++11 is an improvement. I was actually quite excited when Stroustrup's updated book on the subject came out. But like I said, I still can't find a fit for C++ in any of my projects. My use cases however are far different from yours, so I'm naturally opinionated away from C++.
While the C++ language is indeed a superset of the C language, the paradigms of modern C++ have almost no overlap with those of C. See for example the string qsort vs string std::sort elsewhere in this thread.
The myth in "To understand C++, you must first learn C" is not that C and C++ are unrelated. The myth is that learning C helps you understand C++. The reality is that telling people to learn C first is an excellent way of getting them to write really bad C++ when they switch over to C++11.
I'd argue that UB is an evil enough concept in C that still exists and is expanded on in C++ that should be known by every programmer. Sure, paradigm differences mean that idiomatic C code is not idiomatic C++ code, but knowing the pitfalls of the language should be mandatory, imho.
Actually, I've found that it's even undesirable to know C, because programmers, that came from C to C++, usually try to do everything in "C way" that leads to the code is "C with objects". To really learn modern C++, one must "forget" C and start with basic concepts.
Bjarne should know better than to directly compare the performance of std::sort and qsort. One is typically printed in full in a header file, while the other is typically compiled separately. If qsort were found in a header file, it could be inlined into identical code to the C++ version, regardless of the fact that there are void pointers lying around everywhere.
There are caveats: the compiler might not choose to inline unless you force it to, and if you do that then you'll end up with duplicate code in the case of multiple calls with the same comparison function, while C++ can automagically merge duplicates (although you probably want to write a wrapper function anyway, and C++ will still waste compile time generating the duplicates if the calls are in different source files). Also, if the sorting function calls a secondary function in multiple textual locations, and that function is significant enough that inlining it would produce wasteful code, the pure inlining-based approach will be insufficient (but I don't think most sorting algorithms do this).
In other words, C++ makes it easier to do this sort of thing. No surprise! It certainly makes it prettier. But when it comes to performance, in practice the above would likely not be a big deal for qsort, so the difference between the two functions is really more a matter of convention regarding the implementation location. Benchmarking the two and explaining only that type safety "makes for excellent inlining and good optimizations" is simply misleading.
Are you sure that the callback can be inlined though? How would that work, the calls through the pointer would be replaced with the function body? I would assume that qsort itself could be, but that wouldn't help much.
Does compile time really matter that much? I mean, unless you are building a huge project which is expected to take hours to compile, I don't see much benefit in optimizing compile times.
I am working on a project where full rebuild takes about an hour. Fortunately, we do not need to perform full rebuild often on our development machines so most of the time I can build with the changes I've made in between 10 secs to 5 minutes. I would expect this to be similar for other projects.
Surely we care about build speed, but there is no need to care about such micro optimizations as qsort vs std::sort. Most of the speedup is in correctly separating translation units and not including unnecessary header files (sometimes forward declaration is enough for example...).
With that said, when there are some tradeoffs then optimizing build speed is among one of the last things we care about.
To fully rebuild the whole project (U-Boot, Kernel, fs) I'm currently working takes 6 to 8 hours on 8 core i7 and believe me, I've done it may times.. So yes, compile time does matter sometimes.
Of course compile time matters when features like modules provide a significant improvement.
My question was more focused in having to work around the compiler by doing micro-optimizations, or avoiding some features that "may be heavy", just because one project will take 65535ms instead of 65000ms to do a minimal rebuild.
But at the end of the day, it really depends on the dimensions of the project. In a huge project an improvement from 8 hours to 7.5 hours is greatly appreciated.
It matters to me because when I'm "in the zone", every second spent waiting for a compiler to do its thing is a small loss of focus; ideally I'd like incremental compilation time to be below a second. Your brain may be less sensitive to this latency, but I think loss of focus happens to everyone to some extent.
The cost of template instantiations by itself is not too significant, and they ought to be cacheable in the future C++ module system, along with the header file parsing that's the biggest factor making C++ take longer to compile than, say, C. But with today's compilers, it all adds up.
I used a container version of sort() to avoid being explicit about the iterators
Is that something new in C++14, coulnd't immediately find it on the net? Or is it just a version he wrote himself? The latter makes sense for pretty much all algorithms in <algorithm> which you'd use often on a container, to the point you'd start wondering why the standard doesn't provide them built-in.
The C++17 standard should have them, once concepts become a thing; iirc they're not in it now to avoid issues with choosing between sort(Container, Comparator) and sort(Iterator, Iterator) overloads.
That qsort example is getting tedious. I wonder why restrict keyword is never mentioned when talking about C++'s performance advantages over C - it can offer a huge boost on modern CPU architectures. I know it's supported by all major compilers, but still - it's not a part of C++'s standard.
113 comments
[ 3.9 ms ] story [ 225 ms ] thread> “C++ is an Object-Oriented Language”
> “For reliable software, you need Garbage Collection”
> “For efficiency, you must write low-level code”
> “C++ is for large, complicated, programs only”
Well, 2.5/5 of those aren't myths. You certainly don't need to write low-level code for efficiency, C++ does a rather poor job of acting like an OO language, and you don't need Garbage Collection, you just need to not manage memory manually, for which solutions other than GCs exist.
You don't have to learn all of C to write C++, but unfortunately you have to learn C to understand other people's C++, because other people will not restrict themselves to the subset of C++ you consider respectable. That's true both for the C bits of C++ and for the obscenely complex corners of C++.
And C++ isn't just for large, complicated programs; it's for small, complicated programs too.
hahahahahahaha!!!!!!!!!!!!!!!!!!! -- I was thinking that, but hadn't put it into those exact words yet.
I was thinking something like "C++ is definitely for complicated programs" -- not that they necessarily need to be complicated, but that C++ often unnecessarily complicates them.
I really wanted to like the STL a long time ago, but I gave up eventually. Happily my frustration with C++ led me to investigate other programming languages (not that it was the only one I had used), and I write precious little in it lately -- mostly just to modify code others have written in it.
This is an important difference with most subreddits (some, like /r/AskHistorian have a similar ambiance); it avoids ending up with long, heated and shallow conversations.
I didn't just leave it at the onomatopoeia -- I made a very reasonable comment afterwards.
I am not sure which language are you comparing it to but there is definitely a subset of C++ that is easy to use, very readable and type safe.
My only problem with C++ is somebody else code, because there is also a terrible subset of C++ where things can turn very hairy. But same can be said about C, and actually C sometimes encourage you to be "clever".
However, there are multiple other languages that I would rather program in -- although there are still places where I would chose to use C or C++.
I was mostly disappointed that when I tried to use many of the features of C++ that were beyond an intermediate level, the real warts of the language made it not worth the hassle.
I suspect some of that has improved in the latest version of the language spec (and some in the version prior), but I haven't seen anything so far that has excited me enough to get back into it much.
I'll just say I'm not a fan of C++ and would rather write my own language similar to the source-to-source compiler idea of HaXe ( http://haxe.org/ ).
It's the catbirds in the gallery that don't actually have to write the kind of apps that require a language like C++ that "bash" it.
The kernel and git are in C
And if you've been programming C for 20 years or more, writing git with C feels like a natural solution.
It's not always about writing stuff with the most high definition solution, it's more about expressing ideas with the tools you know also.
http://harmful.cat-v.org/software/c++/linus
Quintessential Linus, but I wouldn't call this an "evaluation"... :)
As a side note: I think we as a community should promote the catchphrase "You've Been Torvalds'd".
But since lava layering is caused by cultural and architectural issues I cannot claim that the system would be in any better shape just if some other language had been used.
Let's do something simple, a function that returns a reference to an array of a known size.
Some of C alternatives would be:
or maybe if you have the length somewhere else: or you could try to implement or use an existing implementation of a dynamic array (nothing in the standard as far as I know)vs.
Yes. C is very small and simple. You can learn all of C in a very short time. C++ is the most complex programming language in existence. It is unlikely that there is any person in the world who actually knows it all, including the creators.
>or you could try to implement or use an existing implementation of a dynamic array
Imagine that. You could use libraries that implement things you want. What a concept.
I think I didn't explain myself, but something that basic in these days should be on the standard library in my opinion.
>"Yes. C is very small and simple. You can learn all of C in a very short time."
I don't think C is simple at all. Its syntax can be really cumbersome at times (see my first example). Also it is very annoying to debug, and C code is very prone to contain memory corruption bugs and leaks.
C has great advantages but being simple is not one of them.
Ok well you hop in your delorian and go back to 1970 and let them know. In the mean time, how does that in any way make C not capable for the same tasks as C++?
>I don't think C is simple at all
Then you don't know C. The entire point of C is that it is simple.
>Its syntax can be really cumbersome at times
That has nothing to do with simplicity, and C++ has far more complex syntax.
>Also it is very annoying to debug
C is very simple and straight forward to debug. C++ is much more difficult to debug. Have you ever used either language?
>and C code is very prone to contain memory corruption bugs and leaks.
Because it is so simple.
>C has great advantages but being simple is not one of them.
Well your opinion is in the vast minority, and does not seem to have any basis in reality. The C spec is a tiny fraction of the size of the C++ spec.
Well they could have added in C99 or more recently in C11. What's wrong about updating a language?
> In the mean time, how does that in any way make C not capable for the same tasks as C++?
I would rather prefer not reinventing the wheel and a language that actually ship with it.
> Then you don't know C. The entire point of C is that it is simple.
I know C fairly well to recognize it quirks (just like all languages have). I think your definition of simple is very different of mine. Scheme is simple, InteractiveC is simple, C it is not.
> That has nothing to do with simplicity, and C++ has far more complex syntax.
cumbersome(adj): difficult because of extent or complexity
simple(adj): 1.easily understood or done; presenting no difficulty. antonyms: complex
How come something cumbersome has nothing to do with simplicity?
Also I am not saying that C++ is simple. But it has a subset that it is well defined, type safe and easy to understand.
> C is very simple and straight forward to debug. C++ is much more difficult to debug. Have you ever used either language?
Yes, I have used both in my formal job, and I can avoid memory leaks and memory corruption easily on C++. Not the case on C, specially when working in medium size teams where always people forget what they should cast a void* into and why they should not.
>>and C code is very prone to contain memory corruption bugs and leaks.
>Because it is so simple.
Seriously? It is a feature now? Well Scheme is a good example of language that is order of magnitudes simpler than C and it is not prone to memory leaks nor memory corruptions
>"Well your opinion is in the vast minority, and does not seem to have any basis in reality. The C spec is a tiny fraction of the size of the C++ spec."
If by simple you mean simpler than C++, yeah. You could say the same of Perl. Does is it make Perl a simple language?
Nothing, they do update the language. But fundamentally changing the language to be completely different is not the same as adding some small thing. C is simple on purpose. Adding complexity is not just an update, it is making it no longer suitable for its intended goal. So they choose not to.
>I would rather prefer not reinventing the wheel and a language that actually ship with it.
You don't have to reinvent the wheel, use a library like you already said.
>I think your definition of simple is very different of mine
Clearly. But mine is the same as 90% of the people who have commented on the subject. People overwhelmingly describe C as simple.
>Scheme is simple
Yes it is. As is C.
>How come something cumbersome has nothing to do with simplicity?
You just quoted how. Are you joking?
>Also I am not saying that C++ is simple
But you are arguing that C is complex and thus not appropriate, while C++ is appropriate. You can't have it both ways.
>Yes, I have used both in my formal job, and I can avoid memory leaks and memory corruption easily on C++
Which has what to do with debugging? And why are you incapable of avoiding those problems easily with C when everyone else does it just fine?
>Not the case on C, specially when working in medium size teams where always people forget what they should cast a void* into and why they should not.
Yes, clearly there's no way groups of people could work together on large complex software in C. I'll go tell linux, apache, X, all 4 BSDs, nginx, postgresql, postfix, etc, etc, etc that they don't exist. I'm sure they'll be glad to know.
>Well Scheme is a good example of language that is order of magnitudes simpler than C and it is not prone to memory leaks nor memory corruptions
Scheme is not even one order of magnitude simpler than C. Go read the specs. And scheme is not prone to memory leaks and "corruption" because it is higher level. This also makes it much slower. Even more importantly, it makes it a ridiculous comparison.
>If by simple you mean simpler than C++, yeah.
You are the one advocating C++ over C while claiming C is too complex. What are you blaming me for?
Was it? Most console games are written in C++ in that period of time. A very popular desktop office suite is built on C++. The most popular design and photograph edition tool for Windows is written using C++.
So you are suggesting that all those guys who picked C++ for those popular piece of software are a sort of lucky morons?
It is a strong and risky assertion don't you think?
That is C. Lots of C compilers supported // comments, like watcom which they used. Notice the file extension says it is C. Notice it uses absolutely no C++ features at all.
http://en.wikipedia.org/wiki/RollerCoaster_Tycoon Still using ASM in 1999. Go look at quake 3 which was when id started into C++. Notice how it is barely C++. It seems odd to "suspect I am mistaken" rather than look at the evidence which lines up exactly with what I said.
I don't think RollerCoaster Tycoon is a good piece of evidence because it's famous largely for being written in assembly at a time when most games had already abandoned it.
(Sadly, I don't think it would be odd at all to ignore the evidence, but I aspire to better than that.)
There are still a lot of problem areas where GC is unacceptable, or you need precise control over memory, or access to things like Cuda, along with the high order programming constructs you get in C++.
Maybe Rust will take over some day ...
(It's entirely possible that all six of these languages are terrible, but that would be six separate claims.)
EDIT: DON'T USE THIS, WONT ALWAYS WORK
I can't speak with authority to C#, but C++ is a massively larger core language than Java with far more complicated semantics.
C++11 and C++17 might be quite a pleasure to use when a small team controls all the code, unfortunately most of the real world applications are done in pre-C++98 style.
And then, you still need to learn about each libraries use which version of the standard.
This is why there are so many fundamental types like string duplicated everywhere. We had to rely on third party libraries like Tools.h++ for consistency across compilers and OSs, before the majority reached C++98 compliance.
Well, here you go: https://gist.github.com/ridiculousfish/bb511993deba1d148317
qsort only requires one invocation of the comparator to determine the order, while std::sort often requires two. So qsort ought to be faster when comparisons are expensive.This may be a pathological case for either implementation, since the array is already sorted. Still the point about std::sort requiring up to twice as many comparisons is valid.
qsort: 4415 ms std::sort: 4413 ms
Some comments:
1.) std::sort doesn't require twice as many comparisons
2.) You not only have a vector with equal items, you have a vector of the same item repeated. That removes all data cache issues which I think is generally unrealistic and unfair.
3.) An already sorted vector is not only pathological, it's something that you usually need to optimize for (probably both qsort and std::sort are bad choices)
Oh come on.
Edit: Actually quicksort only needs a stable boolean comparator (e.g., < or >) to determine order. So the number of invocations to the comparator is the same for both qsort and std::sort. Source: http://en.wikipedia.org/wiki/Quicksort
I would amend my top-level comment but I don't seem able to.
• g++ 4.9.2 with O3 qsort 545ms, sort 7289ms
• clang with O3 and libc++ qsort 551ms, sort 844ms
I've used:
andI've updated my tests and qsort seems to be faster than sort, for this particular test case.
EDIT: with clang and libc++, same compilation line otherwise:
For example, the following generates about 2KB of instructions (and will for basically every new type you want to sort):
#include <algorithm>
struct SomeStruct { int X; };
void foo(SomeStruct *SS, int NSS) { std::sort(SS, SS + NSS, [](SomeStruct LHS, SomeStruct RHS) { return LHS.X > RHS.X; }); }
A qsort equivalent will only emit code for the comparator which is just a handful of instructions.
C++ templates may be type safe and all, but at the end of the day they spew duplicated code just as much as those header-only macro-based C containers and algorithms; really more because it's less painful to write templates (vs. macros) and so you do it more, and there is more stuff in the templates. So even though in general the specialized generated code might be faster in most cases (as Bjarne likes to tout), the overall hit on your code size (and i-cache) can be dreadful. Currently, avoiding this issue in C++ just requires diligence on the part of the coder (some optimizations like LLVM's mergefunc can help, but in general it is a pretty hard problem and compilers are not Sufficiently Smart (TM) yet).
LLVM + libclang together are already 46MB of code, and they're libraries designed to be statically linked. Sure, they aren't going to fill your drive, but they will take a comparative while to load from disk (especially as part of another application - doesn't matter much on the command line), and it's that much harder to justify including them in an otherwise small downloaded package.
Edit: it was DICE, see http://www.slideshare.net/DICEStudio/executable-bloat-how-it... - skip to page 14.
This is an interesting optimization, but it's not suitable for a beginner-to-intermediate C++ audience, which is who Stroupstrup is addressing. The sensible default is to use std::sort.
If someone can (and it looks like you have) measure a benefit in doing something special, then she should have at it. If an entire project, again with measurements, can prove that std::sort shouldn't be its default sort algorithm, that's fine too.
I'm not really sure about the rest of the myths. I'm a little confused about how "To understand C++, you must first learn C” is a myth since C++ is a superset of C so you kind of have to learn C.
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n227...
[1] https://gcc.gnu.org/projects/cxx0x.html
Although true, I feel this argument is rather weak: it's true, that when teaching I wouldn't want to start with pointers and malloc's from the get go, but it does not mean C++ is the only alternative.
If you're teaching systems programming, don't hide pointers. In this case, knowing the addition operator is useful iff they understand the underlying operations.... chances are, if they're learning C++, they don't.
It's difficult to find a place for C++ in my little projects, given that I can use C for low level stuff and Python or Lua for high level stuff.
But got to say, my experiences with learning C++11 has changed how I view C++, it's much more robust and nice environment than what I thought, the new C++11 and C++14 really bring some nice things to the table.
The myth in "To understand C++, you must first learn C" is not that C and C++ are unrelated. The myth is that learning C helps you understand C++. The reality is that telling people to learn C first is an excellent way of getting them to write really bad C++ when they switch over to C++11.
There are caveats: the compiler might not choose to inline unless you force it to, and if you do that then you'll end up with duplicate code in the case of multiple calls with the same comparison function, while C++ can automagically merge duplicates (although you probably want to write a wrapper function anyway, and C++ will still waste compile time generating the duplicates if the calls are in different source files). Also, if the sorting function calls a secondary function in multiple textual locations, and that function is significant enough that inlining it would produce wasteful code, the pure inlining-based approach will be insufficient (but I don't think most sorting algorithms do this).
In other words, C++ makes it easier to do this sort of thing. No surprise! It certainly makes it prettier. But when it comes to performance, in practice the above would likely not be a big deal for qsort, so the difference between the two functions is really more a matter of convention regarding the implementation location. Benchmarking the two and explaining only that type safety "makes for excellent inlining and good optimizations" is simply misleading.
which i found shocking, but there it was. my perception was different from the reality.
Surely we care about build speed, but there is no need to care about such micro optimizations as qsort vs std::sort. Most of the speedup is in correctly separating translation units and not including unnecessary header files (sometimes forward declaration is enough for example...).
With that said, when there are some tradeoffs then optimizing build speed is among one of the last things we care about.
Yes. Which is why C++ needs modules. It's a big problem when people have to alter their designs to work around their tools (compilers, in this case).
My question was more focused in having to work around the compiler by doing micro-optimizations, or avoiding some features that "may be heavy", just because one project will take 65535ms instead of 65000ms to do a minimal rebuild.
But at the end of the day, it really depends on the dimensions of the project. In a huge project an improvement from 8 hours to 7.5 hours is greatly appreciated.
The cost of template instantiations by itself is not too significant, and they ought to be cacheable in the future C++ module system, along with the header file parsing that's the biggest factor making C++ take longer to compile than, say, C. But with today's compilers, it all adds up.
Is that something new in C++14, coulnd't immediately find it on the net? Or is it just a version he wrote himself? The latter makes sense for pretty much all algorithms in <algorithm> which you'd use often on a container, to the point you'd start wondering why the standard doesn't provide them built-in.
[1] http://locklessinc.com/articles/vectorize/ [2] http://stackoverflow.com/questions/1965487/does-the-restrict...