People aren't rational actors for a reason: Sometimes things are easy to argue for but aren't that great in practice. And so by following your heart instead of your head, you sometimes make seemingly illogical but objectively better decisions. And I think that there is a case to be made about how C++ is efficient in theory, while C is effective in practice.
You hit my pet peeve right on the head - our instincts, such as fear of the dark, not wanting to touch dead bodies, etc., may be irrational, but there's usually a good reason we have them, and going against them without first understanding them is what is irrational.
> And so by following your heart instead of your head, you sometimes make seemingly illogical but objectively better decisions.
And sometimes you make seemingly illogical decisions that end up being objectively worse decisions. The problem is that we don't really have a way to quantify our emotions usefully, which means we can use them accurately and are forced to allow for enormous amounts of error in our calculations when we provide any level of significance to them. That's why they are often seen as detrimental to rational decisions, not because they don't matter (obviously emotions do), but because including them sometimes leaves us no better off than flipping a coin (are the downsides really that bad, or is your fear of change in this instance vastly overwhelming the other considerations, and in an unwarranted way that you aren't entirely aware of?).
While you have a point that they might sometimes be counter-productive, I think that emotions are decision drivers which operate on a higher abstraction level and are a way for the mind to compile vasts amounts of experience and deliberation into a single really fast circuit able to perform split-second decisions. So I think that they are mostly correct. But it's really too bad that we cannot retoractively introspect them and quantify their grounds.
I agree, but possibly in a different way. The idea of interoception[1] (which I'm not sure how accepted it is) basically means that your feeling are just your body using a heuristic to assign a feeling to a physical state of your body (that is, there is no universal feeling for anger, just a physiological response you've trained your brain to think of as the concept of anger. Some culture's literally do not have certain feelings). Your body is changing physical states based on some subconscious reasoning (often remembered response), and your brain is then interpreting that physiological state broadly and assigning an emotion to it, and it doesn't always get it right (which is why we get angry or anxious sometimes and aren't exactly sure why).
If that theory is true (not sure, I literally just learned about it this morning[1]), your emotions do have weight in something like this, but it's filtered through multiple lossy abstractions and has a propensity for false positives. That's a much less rosy interpretation of how useful they are, and if true, means we might be far better off trying to cultivate a better understanding of the nuances that are causing those reactions and assessing them rationally (to the degree possible) than to using the lossy abstraction itself with any significant weight.
What you're describing is actually rational behavior. You're describing the difference between what you'll imagine beforehand makes more sense vs. what you know will actually work afterwards. The key difference is that you know more than you did in the latter case, so your descisions later have more information to guide them and thus are more likely to be correct.
To think you understood everything before you started and insist on sticking to that after you find it's not working out isn't rational, it's stubborn.
I'm not a big fan of the huge complexity of C++ (and much prefer C in general, although for some things C++ is more convenient) but I don't really think it's fair to dismiss a language based on a small snippet. You can basically mock any language that way:
- In C "getchar" returns... an int.
- Pointers and array are kinda the same thing, but not exactly. The rules for when an array decays into a pointer are sometimes unintuitive and surprising.
- Same thing for the implicit integer types promotions.
- `char *s = "foo"` is not at all the same thing as `char s[] = "foo"`. Arguably the former should be considered erroneous, but compiles just fine in C. G++ gives a warning for the same code however.
- There's also the ridiculous "gets" function that's so poorly designed it could be part of PHP. This one finally got officially deprecated though.
Of course many of these issues are also part of C++ since it's mostly a superset of C but in general it's stricter and more strongly typed.
A good example of human behavior in TFA as well as the talk it cites is how deeply convinced they are that C++ is objectively always better than C; they don't even try to suggest that there could be a tradeoff and sometimes C would be better. Of course the guy in the talk makes a living from C++ consulting; another part of human behavior is it's hard to convince someone of a truth which threatens their paycheck.
And I'm not here to argue how terrible C++ is (I've done enough of that elsewhere), but only that "behavioral" arguments cut both ways, and are usually little more than an ad hominem attack and/or some good old marketing tricks rebranded as "behavioral science."
> And I'm not here to argue how terrible C++ is (I've done enough of that elsewhere)
Haha that's one way to put it :p
For those new to this debate: Yosef Kreinin is the author of the (in)famous C++ Frequently Questioned Answers.[0] it's quite a body of work. Speaking of which: thanks for writing it, Yosef. I greatly enjoyed reading it back in the day, and it had a big impact on young me.
Glad you liked it! It is unfortunately quite out of date as it does not address C++11/14/17; so I put it on github in the hope that people would take over it, as I personally no longer care enough to invest the time it takes (at most I might publish a blog post on this, working title: Modern C++ Feels Just Like Python, My Ass.)
Yeah, I see this trend in "behavioral science" arguments in other areas of debate.
It's especially funny to watch people on both sides of whatever issue argue that the side they're opposed to is in a self-reinforcing bubble that only closes them to the beliefs of their team, which are obviously correct. But, the thought process that produces the belief that their team is correct is incubated in exactly the same sort of bubble that they're complaining about.
And a good example in the comments here is how few people are talking about what the article is actually about (human behaviour) but instead there's mostly anti-C++ reactions. The aversion to C++ is so strong that an article that only casually is about C++ must be attacked for the perceived C++ advocacy. The article isn't really about C++ advocacy at all.
It really doesn't matter if C++ is better or not. The article doesn't really even try to talk much about that at all. No matter what C++ may do, what it may change, what it may improve, how it may perform, how it can be simplified; it's almost impossible to convince C programmers to try C++ (or golang, or Rust, or D).
The article really is about how it's almost impossible to change someone's mind on any topic. Anyone who likes to engage in internet discussions is well aware of the phenomenon.
To be honest the article's kind of bullshit regardless of what angle you view it from. Some of my favourite parts are:
> the fundamental energy that underlies and is responsible for the universe is consciousness. So consciousness is inherently logical.
> Since humans are a part of the universe ... humans are also logical or rational by nature.
> We’re born with the need for sexual satisfaction, yet society teaches us ... to suppress and even repress our sexuality. This is one of the most important seeds for irrational thinking that gets planted into our minds.
There's enough pseudo-scientific bullshit on the rest of this person's site that I'm very wary of drawing any conclusions from this article.
The article is a 4,000 word diatribe about how stubborn, irrational people refuse to see reason, without at any point admitting the possibility that these backward, incorrigible C holdouts could be right in any way.
It's not about C holdouts being unreasonable at all. They're only mentioned in the first three paragraphs of the article. The article isn't about C or C++. It's about why you and I are arguing right now: we're both irrational.
> It's not about C holdouts being unreasonable at all. They're only mentioned in the first three paragraphs of the article.
That's not true; they are mentioned several times in the first big bullet list. Also the Dan Saks talk he discusses several times throughout the article is specifically about talking to C programmers about C++.
But regardless of whether he is speaking about something specific (C vs. C++) or in the abstract (rational vs. irrational people), he is making the same flawed presumption: that certain choices (like C++) are unquestionably better than other choices (like C), and that if people can't see this then the only possible explanation is some kind of cognitive impairment.
The whole argument presumes that the author is smarter and more rational than other people. He might not even realize he is doing this, but other people can most definitely pick up on it.
> The whole argument presumes that the author is smarter
Aha, so that's why everyone is posting comments about how terrible C++ is. The author is coming across like an ass, so we must attack that which he appears to be defending: C++.
I don't really pick up on the bad attitude (probably because I have it too), and I don't really care that much to defend C++ or C. I went through the article, noted a few references to whatever psychological studies were there, and decided to read those later. I don't really care if C or C++ is "better". I barely use either anymore.
In a lengthy piece about rational arguments, you would expect somewhere in there someone would actually present a rational argument for switching beyond "it's modern."
I mean, maybe the actual details of the case for switching are slightly beyond the scope the author intended to write about, but simply starting with an assertion that "modern = better, therefore people should have already switched if they were rational" and treating that as self-evident strikes me as highly arrogant and logically fallacious.
Be careful comparing complexity. C might look simple, and C++ might look complex but I have never seen a char* in C++ to mean 2d of jpg images in memory.
C++ is more complex, because it covers more concepts. But when you get simple safe and to reusable things from that complex the difficulty is reduced.
What is the right way to store and unknown amount of things in C?
There are about a million ways to do and every project will implement their and about half will work. Of that half maybe 1 in 10 will have an API that is intuitive to the reader, and depending on the reader that 1 in 10 will be different. Now what if what you an associative container instead?
With C++ just using std::vector, because this is a solved. (or map/unordered map for the associative container).
This continues on with libraries. Every API needs to have a large series of questions answered every time you pass a pointer. Because C has no concept of ownership who is supposed to delete it? Without const references extra caution to distinguish const pointers and pointers to const things, why is this important? Without templates writing an API that works on multiple types involves dealing with void* at run time, presuming you don't want to actually use anything in the data.
C looks simpler because it is smaller. C++ is easier and simpler because it has already dealt with many of the hard problems.
LOL, C++ developers complain about C developers being impervious to reason, yet can't admit one of the most blindly obvious problems with C++. Plenty of language manage to be more expressive than C++ while being far less complex. C++ is an uncritical grab bag of features. If you don't carefully design features to complement each other you can C++ style complexity.
C simplicity is real. It makes it easy to write compilers. Compare with the enormous complexity of writing a C++ compiler. This is actually quite important as any software development needs tools. Writing tools for simple languages is easier. Writing tools for C++ is next to impossible. Most of my C++ career I have never had proper refactoring tools. I haven't even been able to use a lot of C++ features because it has taken so many years for all compiler writers to implement all the features.
I can't think of a single other language where it has been so many years of lag between a language specification and it being widely adopted among major compilers.
The simplicity of C makes it easy to interface C with a huge number of other languages. C++ can't interface with almost anything. It is just way too complex.
A much saner superset of C, is Objective-C which can actually interface very easily with other languages.
You are lumping me in with some strawman who insulted you, then you insult me calling me "impervious to reason". You are not interested in a real exchange of ideas.
I will respond to your points in the spirit of open exchange anyway, but if you continue to be rude it will just shine a poor light on C programmers as a whole. Since I feel you ideas are lacking factually this might seem like an attack, it is not an attack and I even ask for more information on points with merit.
I have pointed out that elsewhere in this thread that the standardized C ABI is perhaps the only thing I like about it. C++ can seamlessly use this, but not by default (which is a weakness of C++). So anything C inter-operates with C++ can too. So your point that C++ inter-operates with less is entirely without merit. Using this I have interoperated with Lua and Ruby from C++, it works well.
To push interop further there are several tools like SWIG that seek to allow exchange of rich objects between languages (rich objects that C doesn't even have), and these tools work. I have written code that throws exceptions from Java an catches them in C++ (and vice versa of course) and things of similar complexity in a few other languages.
It feels fantastic to have low or 0 cost abstraction around passing complex objects between systems and have all the code that does that strongly checked at compile time (And covered in Unit tests too that but that could be done in C too, I just don't see it often).
As for tooling, I again think your points are largely without merit. The are plenty of tools for both languages and there are plenty of simpler languages with less tools. It seems to me that the amount of tooling is not related to complexity but rather popularity of the language.
A language that is functionally driven by one vendor and supplanted by that vendor with a newer language (swift) is not a reasonable solution to most problems. I am curious about we makes it interop better than interop with C++, what does it do right that C++ does wrong?
If we were discussing two languages Strawberry and Kiwi, and I had a large, established codebase in Strawberry and a bunch of programmers who are experts in Strawberry, it would be a hard sell to get me to switch to Kiwi even if Kiwi were better than Strawberry in every conceivable way and backwards compatible with it to boot:
- Learning to use a new system effectively takes time and energy. Are you 100% sure that the benefit of the new system is great enough to offset these costs?
- Hybrid codebases have higher maintenance costs than homogeneous ones. If Kiwi mixes with Strawberry seamlessly, maybe that burden is lower—but the more true that is, the harder it is to believe that moving to Kiwi confers a large advantage.
In this specific case, I could believe that C++ by seasoned C++ users leads to demonstrable net gains. But it's easier for me to believe that switching to Rust or Haskell would confer higher gains, corresponding to the higher risk and higher cost of switching. So I think it's not that people are irrational about avoiding C++. I think that C++ is in an awkward place on the hill between C and things better than C++. If you need something better, you will go to something with better tradeoffs than C++; if you don't need something better, you just live with your existing C codebase.
One of the major problems I have with C++ is that for any non-primitive data type, there are way too many choices of mutually incompatible classes that people have developed. Even strings. There are things out there that use char[], std::string, CString, APString (#*&!), ...
In the sense that OOP is often used in very stupid ways (dunno about C++ but in other languages, have a look at PHPUnit it is the best example of misunderstood OOP) I can understand C programmers. Golang is also very simple for a reason
I agree, but moreover: You can also do nice OOP with C.
Take a look, for example, to COS (C Object System) which implements OOP on top of your C compiler. The object system itself is inspired by CLOS (Common Lisp Object System) and Objective-C (in turn inspired by Smalltalk). It also allows 'automatic' allocation by reference counting.
> The C++ language is an improved version of the older C language (it’s a superset of C),
The first statement is arguable and the parenthetical statement is false. C99/C11 have language features that C++ hasn't adopted, which makes it somewhat obnoxious to support C++ from C codebases that use them. One example is the "static" keyword used in array parameters.
“If you’re arguing, you’re losing.”. That is a quick way to stop any discussion. The reason I am not using C++ is because C already does everything I need:
- Easier to write code generators for: I use libclang to read in annotations that will generate new code according to where the annotations are being used. If I have to take care of every edge case and new features added to the latest C++ standard it would make the code generator more complex.
- Using plain old data structures: My code generator generates new code to be able to work with the plain old data structures which data can be interleaved or non-interleaved using data-oriented design. Classes will not add that much value.
- C compilers are easier to write: I integrated the tiny C compiler inside my program to be able to compile C code on demand. The C code can then use the code I've already written.
- No name mangling by default: I dynamically load a lot of plugins and do not want to bother with binary incompatibilities all the time (if compiled by different compilers like the tiny C compiler for ex.).
- I mostly use libraries written in C
- Low-level access
If I need concepts or meta-programming etc.
I can already use Nim or write my own code generator,
else I would rather choose something different than C++.
To be more on-topic. Confirmation bias. On The Internet you can find confirmation of something being true about almost every topic. Whatever people believe is the truth, it will not change the reality. Which programming languages are better is a very difficult thing to measure because there are many factors to consider. Being used to a certain programming language can be a good reason not to change.
1) By using libclang to parse your own annotations you're kind of using your own fork of C language, not the standard one. You can't really bring your annotation parsing engine to some company to work on an existing C project,
2) C++ also uses plain old data structures, using 'class' does not magically introduce any overhead in structures, unless you start using virtual functions, but nothing forces you to do it,
3) I think that by stripping name mangling you actually increase binary incompatibility, because without mangling you can't know what ABI was the function compiled against. Which compiler was it? What are the arguments? Is it MS ABI or UNIX ABI? Nobody knows for sure even if it seems to work correctly for some set of arguments. Disabling mangling sure is convinient at the beginning, but brings problems and incompatibilities at later stage.
4) Given that Windows or macOS kernel drivers are written in C++ (more or less), low level access is possible in C++ as well.
I am aware that all of this is possible in C++ as well and for many things C++ might be the better choice (more standardized compiler hints instead of using pragmas, generics and templates etc.).
What I meant is that C++ does not add anything for me personally.
POD-structures are all I need and the way I fetch/store the data may require the struct layout to be interleaved or non-interleaved (depending on the platform / architecture I am targeting for a specific build) requiring different code to be generated to access them.
I do not need to disable name mangling or add 'extern "C"' everywhere (I still do in case the code will be used from C++) when I just use plain C.
I like the many new features added to C++ like concepts, lambdas etc. but for these I prefer to use Nim (they just added complete concept support as well).
This reminds me of Godel's proof - A formal system (axiomatic system) cannot be complete and consistent at the same time!
Each side of the argument have their own set of premises/axioms to come to certain conclusions but there are always unknown truths which people tend to ignore. if there are no unknown truths then the argument should be contradictory
>* Based on research by Kahan et. al., Saks mentions that otherwise intelligent people will likely misunderstand data if understanding it challenges their preexisting beliefs.*
While this happens, it's also an empty argument that can be applied to everything.
How about the author there misunderstands his own data on C++ because it challenges his preexisting beliefs (that C++ is "de facto" better)?
It goes downhill from there fast, to argue that those pesky people who dare to not want to use C++ are irattional, conditioned from childhood, etc (those willing to use C++ are not, because of course C++ is the only reasonable choice a programmer can ever make between C and C++).
>In fact, Saks found that quite often logic, facts and the truth were simply not sufficient enough to convince people. Instead, people reacted in a very irrational and emotional way, and kept sticking to and defending their beliefs. People’s basic reaction was “show me all the data you want, C++ is still undesirable.”
The problem in the paper is that some BS arguments and numerical data in favor of C++ (which I'm assuming they have -- they fail to mention any of them in this article) are conflated for "THE truth".
Sorry, author, but you are not showing people "THE reality", you're showing them some arguments and some numbers.
The programmers you are talking to (those that have tried both C and C++) are the ones that have actual empirical experience from actual reality on what C++ gets them -- and whether its worth the tradeoffs they've seen.
For one, there's an ergonomic factor in language and API design (it's usability) which can be highly subjective -- and syntax/api usability is one of the big reasons people dislike C++. This issue cannot be shot down with any "objective" argument or numbers table....
At a cultural level, when you have to convince somebody of something, isnt that generally a bad approach if you want somebody to change their view?
Though, Keeping thIngs Simply Stupid, is really the only lesson one has to know/learn. When C++ has a specific function go with C++, when C is sufficient use C. If a bash script is sufficient use that.
If people could just show why something is cool in what situation, instead of why something should be used over something else. And this includes guides 'how to switch desktop OS' too.
"- Show how the STL makes most things easier (arrays, maps, etc)"
The problem with the STL is that you are always running into roadblocks when you try to compose things. I tried for a very long time to like the STL, and in the end it was very very good for one thing -- pushing me to look for something better.
I suspect things have improved some with the newer C++ standards (it's probably been almost 10 years since I gave up doing much of what I wanted to do in C++), but I much prefer Lisp, Scheme, and other languages now (most, if not all of them dynamically typed). Learning Lisp-family languages did indeed change how I program in other languages -- IMHO greatly improving the way I write code.
I might revisit C++ at some point, just to see what's happening there. I've only skimmed a few articles about the newer standards, and some things look promising. But it would probably take my involvement in a real-world project that uses C++ to get me to go there. I've just spent way too many frustrating hours trying to get things to work the way I wanted in C++.
I'm going to flip the discussion a bit, and ask, what is a good use of operator overloading? What is a bad one? Is it possible to generalize the rules around good vs. bad cases (in order to make a programming standard others can follow)?
My experience is that I like writing code that uses operator overloading, but hate reading code that has it. Kind of like programming in Perl. In both cases, I find that on large projects, it is best to avoid the technology.
> In fact, Saks found that quite often logic, facts and the truth were simply not sufficient enough to convince people. Instead, people reacted in a very irrational and emotional way, and kept sticking to and defending their beliefs.
You start criticizing people for not believing you when you have one example comparing two different programs implementing an unspecified task on an unspecified compiler. This is ridiculous.
I mean, for crying out loud, your headlining video is a talk by a person who admits that he hasn't done the thing he's trying to convince people to do.
He says things like this:
"You don't want to wait for the market to take care of this, you would like to take some proactive steps to be able to make more of the people who should be using C++ willing to use it."
in the context of aerospace, which clearly he has no authority to speak on, since he misses one of the fundamental reasons why C++ is not popular or even acceptable in much of aerospace: implicit allocation. Implicit allocation is incredibly dangerous for high assurance systems. You really need to know exactly how much memory can be allocated, when, and what state the exact allocations will put the allocator in. C++ has some facilities to manage this, but man, it is easy to drop a plane from the sky by assuming that your allocation did what you wanted instead of verifying it.
Scott Meyers points out that one of the simplest possible refactorings is "rename method". To rename f(), you need to know what f() is, and in C++, f() can be any of 7+ different things! [0] It's extremely complicated to determine which thing it is.
But according to TFA, people who prefer C are just being emotional and irrational.
In some obscure technical sense you might be correct, that identifying some piece of code is hard, but that little of C++ obscurantism is rarely why code isn't easy to read.
With C++ it easier to express higher level concepts. I can have a map of strings to some class instance. Then I can use some string to lookup class instances. There are simple idiomatic ways to do this. They are short to writes (<10 lines), they will have decent performance and will be low on bugs and clear ownership semantics.
With C it is common to have an array of pointer to pointer to void pointers. To get associative lookup it might be even worse and have functions that need to pointer to pointers, with who knows what ownership model and what idioms in use.
I've noticed that the best way to get programmers to use a different language is to build something they want to use in that language.
I could talk to my perl programming colleagues for days about the advantages of python over perl, but what got them to switch was boto, since we were moving to aws.
C++ impregnates the tissues, and then it hardens and settles like silt. It makes your aorta stiffer than a hockey stick. Whereas C caresses your insides, leaving nothing behind but its scent
I do not fully agree with the premise that C programmers don't know what's best for them and need to be educated to switch to C++. I do agree that C++(14++) isolated is a better programming language in many ways compared to C. The problem is that a programming language seldom is used isolated, but is part of a toolchain or is used in an environment with other technologies.
In this situation, C is a much better choice because most other languages have nice interoperability with C, but seldom, if ever, with C++. For example, as an iOS developer I can use C and C-libraries very easy with Swift, while inter opt with C++ is not possible at all and probably never will.
The main thing keeping me away from C++ is that it does not have a stable common ABI. This makes it very nearly impossible to use C++ to create and distribute a shared library. I even believe Google developers internally are prohibited from creating C++ libraries for this reason. So I'm sticking with C for low level stuff. It's a perfect glue language and fast. For higher level stuff, why use C++, when you can use Swift, Java, Haskell etc etc?
Why do programmers feel the need to convince other programmers to switch to a different language? How does it affect Programmer A, a C++ programmer, whether or not programmer B prefers to use C? I like both C and C++. I also like Objective-C, Ruby, and Python. Each one has its place--and if I'm starting a new project, I'll use the one that makes the most sense to use given the project's requirements--or a mix of them if it's appropriate. If I'm joining a project in-progress, I'm happy to use whatever language has already been chosen. Why get into religious wars?
> Why do programmers feel the need to convince other programmers to switch to a different language?
Because they themselves derived some benefit from it, and believe the other party would too, if only they would try it.
Sometimes, I don't think it's just benefits, but certain languages offer different ways of doing things that other languages really could benefit from. Our older languages teach us things as we use them, like that nullable pointers as our only reference type were a bad idea. Encouraging others to use languages that adopt different ideals would seem to be to just be people trying to get people to see the merits of those ideals.
> Why get into religious wars?
Because we're still using languages with nullable pointers. More seriously, because people care about the quality of their work, and you don't always get to pick the tool for the job. And it can very well be that there isn't a good tool for the job, but only and okay tool for the job: while I use Python extensively at my job, and while its speed of development definitely benefits my team, I would kill for some static typing. (I've been looking into mypy for this reason, but being on Python 3 would help…)
And people don't always use the right tool for the job, or I'd be done trying to explain why they should not be using raw bytestrings for text. They didn't pick the wrong tool for the job — they simply don't understand that actual string types exist, or why they should use them. (It doesn't help when the language/library's obvious choice is the wrong choice.)
According to Alan Kay, programming is a pop culture right now. So people want to preserve the investment in the language of their choice by maintaining or improving its pop status.
I don't want to maintain a giant heap of buggy C Code.
I don't want to deal with bugs in the JVM/JNI.
I want ownership semantics expressed in code. When a C functions accepts or return a pointer who deletes it?
I want code to be easily tested, automatically. Common C code has so much shared mutable state that unit tests are rare, and when used are trumpeted as masterworks of engineering like the sqllite test suite.
C makes all these things hard or impossible to work with. From my perspective, the only positive it brings in the standardized ABI.
86 comments
[ 2.9 ms ] story [ 137 ms ] threadI still vastly prefer C++ over C though :P
And sometimes you make seemingly illogical decisions that end up being objectively worse decisions. The problem is that we don't really have a way to quantify our emotions usefully, which means we can use them accurately and are forced to allow for enormous amounts of error in our calculations when we provide any level of significance to them. That's why they are often seen as detrimental to rational decisions, not because they don't matter (obviously emotions do), but because including them sometimes leaves us no better off than flipping a coin (are the downsides really that bad, or is your fear of change in this instance vastly overwhelming the other considerations, and in an unwarranted way that you aren't entirely aware of?).
If that theory is true (not sure, I literally just learned about it this morning[1]), your emotions do have weight in something like this, but it's filtered through multiple lossy abstractions and has a propensity for false positives. That's a much less rosy interpretation of how useful they are, and if true, means we might be far better off trying to cultivate a better understanding of the nuances that are causing those reactions and assessing them rationally (to the degree possible) than to using the lossy abstraction itself with any significant weight.
1: http://www.pc.rhul.ac.uk/sites/lab/index.php/research-themes...
2: http://www.npr.org/podcasts/510307/invisibilia
To think you understood everything before you started and insist on sticking to that after you find it's not working out isn't rational, it's stubborn.
But according to OP, it's not C++ that's irrational, it's the programmers who don't want to use C++.
[0] https://twitter.com/sigfpe/status/857748171778252800 [EDIT: corrected broken link]
- In C "getchar" returns... an int.
- Pointers and array are kinda the same thing, but not exactly. The rules for when an array decays into a pointer are sometimes unintuitive and surprising.
- Same thing for the implicit integer types promotions.
- `char *s = "foo"` is not at all the same thing as `char s[] = "foo"`. Arguably the former should be considered erroneous, but compiles just fine in C. G++ gives a warning for the same code however.
- There's also the ridiculous "gets" function that's so poorly designed it could be part of PHP. This one finally got officially deprecated though.
Of course many of these issues are also part of C++ since it's mostly a superset of C but in general it's stricter and more strongly typed.
> decltype(auto) f1(){int x = 0; return x;}
> decltype(auto) f2(){int x = 0; return (x);}
> Latter, not former, returns reference to int.
If the fastest one took 100s, then the one taking x1.57 took 157s.
I shouldn't have made either of these posts.
And I'm not here to argue how terrible C++ is (I've done enough of that elsewhere), but only that "behavioral" arguments cut both ways, and are usually little more than an ad hominem attack and/or some good old marketing tricks rebranded as "behavioral science."
Haha that's one way to put it :p
For those new to this debate: Yosef Kreinin is the author of the (in)famous C++ Frequently Questioned Answers.[0] it's quite a body of work. Speaking of which: thanks for writing it, Yosef. I greatly enjoyed reading it back in the day, and it had a big impact on young me.
[0] http://yosefk.com/c++fqa/
It's especially funny to watch people on both sides of whatever issue argue that the side they're opposed to is in a self-reinforcing bubble that only closes them to the beliefs of their team, which are obviously correct. But, the thought process that produces the belief that their team is correct is incubated in exactly the same sort of bubble that they're complaining about.
It really doesn't matter if C++ is better or not. The article doesn't really even try to talk much about that at all. No matter what C++ may do, what it may change, what it may improve, how it may perform, how it can be simplified; it's almost impossible to convince C programmers to try C++ (or golang, or Rust, or D).
The article really is about how it's almost impossible to change someone's mind on any topic. Anyone who likes to engage in internet discussions is well aware of the phenomenon.
> the fundamental energy that underlies and is responsible for the universe is consciousness. So consciousness is inherently logical.
> Since humans are a part of the universe ... humans are also logical or rational by nature.
> We’re born with the need for sexual satisfaction, yet society teaches us ... to suppress and even repress our sexuality. This is one of the most important seeds for irrational thinking that gets planted into our minds.
There's enough pseudo-scientific bullshit on the rest of this person's site that I'm very wary of drawing any conclusions from this article.
That's not true; they are mentioned several times in the first big bullet list. Also the Dan Saks talk he discusses several times throughout the article is specifically about talking to C programmers about C++.
But regardless of whether he is speaking about something specific (C vs. C++) or in the abstract (rational vs. irrational people), he is making the same flawed presumption: that certain choices (like C++) are unquestionably better than other choices (like C), and that if people can't see this then the only possible explanation is some kind of cognitive impairment.
The whole argument presumes that the author is smarter and more rational than other people. He might not even realize he is doing this, but other people can most definitely pick up on it.
Aha, so that's why everyone is posting comments about how terrible C++ is. The author is coming across like an ass, so we must attack that which he appears to be defending: C++.
I don't really pick up on the bad attitude (probably because I have it too), and I don't really care that much to defend C++ or C. I went through the article, noted a few references to whatever psychological studies were there, and decided to read those later. I don't really care if C or C++ is "better". I barely use either anymore.
I mean, maybe the actual details of the case for switching are slightly beyond the scope the author intended to write about, but simply starting with an assertion that "modern = better, therefore people should have already switched if they were rational" and treating that as self-evident strikes me as highly arrogant and logically fallacious.
Unless... they didn't actually think that much about the topic. I dunno. I didn't watch the video so I don't know if it's in there.
C++ is more complex, because it covers more concepts. But when you get simple safe and to reusable things from that complex the difficulty is reduced.
What is the right way to store and unknown amount of things in C?
There are about a million ways to do and every project will implement their and about half will work. Of that half maybe 1 in 10 will have an API that is intuitive to the reader, and depending on the reader that 1 in 10 will be different. Now what if what you an associative container instead?
With C++ just using std::vector, because this is a solved. (or map/unordered map for the associative container).
This continues on with libraries. Every API needs to have a large series of questions answered every time you pass a pointer. Because C has no concept of ownership who is supposed to delete it? Without const references extra caution to distinguish const pointers and pointers to const things, why is this important? Without templates writing an API that works on multiple types involves dealing with void* at run time, presuming you don't want to actually use anything in the data.
C looks simpler because it is smaller. C++ is easier and simpler because it has already dealt with many of the hard problems.
C simplicity is real. It makes it easy to write compilers. Compare with the enormous complexity of writing a C++ compiler. This is actually quite important as any software development needs tools. Writing tools for simple languages is easier. Writing tools for C++ is next to impossible. Most of my C++ career I have never had proper refactoring tools. I haven't even been able to use a lot of C++ features because it has taken so many years for all compiler writers to implement all the features.
I can't think of a single other language where it has been so many years of lag between a language specification and it being widely adopted among major compilers.
The simplicity of C makes it easy to interface C with a huge number of other languages. C++ can't interface with almost anything. It is just way too complex.
A much saner superset of C, is Objective-C which can actually interface very easily with other languages.
I will respond to your points in the spirit of open exchange anyway, but if you continue to be rude it will just shine a poor light on C programmers as a whole. Since I feel you ideas are lacking factually this might seem like an attack, it is not an attack and I even ask for more information on points with merit.
I have pointed out that elsewhere in this thread that the standardized C ABI is perhaps the only thing I like about it. C++ can seamlessly use this, but not by default (which is a weakness of C++). So anything C inter-operates with C++ can too. So your point that C++ inter-operates with less is entirely without merit. Using this I have interoperated with Lua and Ruby from C++, it works well.
To push interop further there are several tools like SWIG that seek to allow exchange of rich objects between languages (rich objects that C doesn't even have), and these tools work. I have written code that throws exceptions from Java an catches them in C++ (and vice versa of course) and things of similar complexity in a few other languages.
It feels fantastic to have low or 0 cost abstraction around passing complex objects between systems and have all the code that does that strongly checked at compile time (And covered in Unit tests too that but that could be done in C too, I just don't see it often).
As for tooling, I again think your points are largely without merit. The are plenty of tools for both languages and there are plenty of simpler languages with less tools. It seems to me that the amount of tooling is not related to complexity but rather popularity of the language.
A language that is functionally driven by one vendor and supplanted by that vendor with a newer language (swift) is not a reasonable solution to most problems. I am curious about we makes it interop better than interop with C++, what does it do right that C++ does wrong?
Hey now, most of us have nothing in particular to do with this guy!
- Learning to use a new system effectively takes time and energy. Are you 100% sure that the benefit of the new system is great enough to offset these costs?
- Hybrid codebases have higher maintenance costs than homogeneous ones. If Kiwi mixes with Strawberry seamlessly, maybe that burden is lower—but the more true that is, the harder it is to believe that moving to Kiwi confers a large advantage.
In this specific case, I could believe that C++ by seasoned C++ users leads to demonstrable net gains. But it's easier for me to believe that switching to Rust or Haskell would confer higher gains, corresponding to the higher risk and higher cost of switching. So I think it's not that people are irrational about avoiding C++. I think that C++ is in an awkward place on the hill between C and things better than C++. If you need something better, you will go to something with better tradeoffs than C++; if you don't need something better, you just live with your existing C codebase.
I'll also add QString, AnsiString, BSTR and glib::ustring to the mix :)
https://github.com/CObjectSystem/COS
Paper: https://arxiv.org/abs/1003.2547
The first statement is arguable and the parenthetical statement is false. C99/C11 have language features that C++ hasn't adopted, which makes it somewhat obnoxious to support C++ from C codebases that use them. One example is the "static" keyword used in array parameters.
- Easier to write code generators for: I use libclang to read in annotations that will generate new code according to where the annotations are being used. If I have to take care of every edge case and new features added to the latest C++ standard it would make the code generator more complex.
- Using plain old data structures: My code generator generates new code to be able to work with the plain old data structures which data can be interleaved or non-interleaved using data-oriented design. Classes will not add that much value.
- C compilers are easier to write: I integrated the tiny C compiler inside my program to be able to compile C code on demand. The C code can then use the code I've already written.
- No name mangling by default: I dynamically load a lot of plugins and do not want to bother with binary incompatibilities all the time (if compiled by different compilers like the tiny C compiler for ex.).
- I mostly use libraries written in C
- Low-level access
If I need concepts or meta-programming etc. I can already use Nim or write my own code generator, else I would rather choose something different than C++.
To be more on-topic. Confirmation bias. On The Internet you can find confirmation of something being true about almost every topic. Whatever people believe is the truth, it will not change the reality. Which programming languages are better is a very difficult thing to measure because there are many factors to consider. Being used to a certain programming language can be a good reason not to change.
https://en.wikipedia.org/wiki/Confirmation_bias
Update: added some explanations, and more on-topic
1) By using libclang to parse your own annotations you're kind of using your own fork of C language, not the standard one. You can't really bring your annotation parsing engine to some company to work on an existing C project,
2) C++ also uses plain old data structures, using 'class' does not magically introduce any overhead in structures, unless you start using virtual functions, but nothing forces you to do it,
3) I think that by stripping name mangling you actually increase binary incompatibility, because without mangling you can't know what ABI was the function compiled against. Which compiler was it? What are the arguments? Is it MS ABI or UNIX ABI? Nobody knows for sure even if it seems to work correctly for some set of arguments. Disabling mangling sure is convinient at the beginning, but brings problems and incompatibilities at later stage.
4) Given that Windows or macOS kernel drivers are written in C++ (more or less), low level access is possible in C++ as well.
What I meant is that C++ does not add anything for me personally.
POD-structures are all I need and the way I fetch/store the data may require the struct layout to be interleaved or non-interleaved (depending on the platform / architecture I am targeting for a specific build) requiring different code to be generated to access them.
I do not need to disable name mangling or add 'extern "C"' everywhere (I still do in case the code will be used from C++) when I just use plain C.
I like the many new features added to C++ like concepts, lambdas etc. but for these I prefer to use Nim (they just added complete concept support as well).
Each side of the argument have their own set of premises/axioms to come to certain conclusions but there are always unknown truths which people tend to ignore. if there are no unknown truths then the argument should be contradictory
While this happens, it's also an empty argument that can be applied to everything.
How about the author there misunderstands his own data on C++ because it challenges his preexisting beliefs (that C++ is "de facto" better)?
It goes downhill from there fast, to argue that those pesky people who dare to not want to use C++ are irattional, conditioned from childhood, etc (those willing to use C++ are not, because of course C++ is the only reasonable choice a programmer can ever make between C and C++).
>In fact, Saks found that quite often logic, facts and the truth were simply not sufficient enough to convince people. Instead, people reacted in a very irrational and emotional way, and kept sticking to and defending their beliefs. People’s basic reaction was “show me all the data you want, C++ is still undesirable.”
The problem in the paper is that some BS arguments and numerical data in favor of C++ (which I'm assuming they have -- they fail to mention any of them in this article) are conflated for "THE truth".
Sorry, author, but you are not showing people "THE reality", you're showing them some arguments and some numbers.
The programmers you are talking to (those that have tried both C and C++) are the ones that have actual empirical experience from actual reality on what C++ gets them -- and whether its worth the tradeoffs they've seen.
For one, there's an ergonomic factor in language and API design (it's usability) which can be highly subjective -- and syntax/api usability is one of the big reasons people dislike C++. This issue cannot be shot down with any "objective" argument or numbers table....
C# is more what Java should have been (which lines up pretty well with the history of C#).
Though, Keeping thIngs Simply Stupid, is really the only lesson one has to know/learn. When C++ has a specific function go with C++, when C is sufficient use C. If a bash script is sufficient use that.
If people could just show why something is cool in what situation, instead of why something should be used over something else. And this includes guides 'how to switch desktop OS' too.
- Show them how classes makes things easier (automatic object management, some operator overloading, etc)
- Show how the STL makes most things easier (arrays, maps, etc)
How not to convince them:
- Show uses of excessive/pathological inheritance
- Use of templating beyond the basics
- Insist they use C++ functions for every single thing
- Insist they OOify every interface in their code
- Creating giant classes (structs) with a getter and setter for every field with no control or validation
- Going crazy with operator overloading
The problem with the STL is that you are always running into roadblocks when you try to compose things. I tried for a very long time to like the STL, and in the end it was very very good for one thing -- pushing me to look for something better.
I suspect things have improved some with the newer C++ standards (it's probably been almost 10 years since I gave up doing much of what I wanted to do in C++), but I much prefer Lisp, Scheme, and other languages now (most, if not all of them dynamically typed). Learning Lisp-family languages did indeed change how I program in other languages -- IMHO greatly improving the way I write code.
I might revisit C++ at some point, just to see what's happening there. I've only skimmed a few articles about the newer standards, and some things look promising. But it would probably take my involvement in a real-world project that uses C++ to get me to go there. I've just spent way too many frustrating hours trying to get things to work the way I wanted in C++.
I really can't see what C++ has to offer anybody. It is a horribly complex language, which doesn't interface with anything except C.
My experience is that I like writing code that uses operator overloading, but hate reading code that has it. Kind of like programming in Perl. In both cases, I find that on large projects, it is best to avoid the technology.
You start criticizing people for not believing you when you have one example comparing two different programs implementing an unspecified task on an unspecified compiler. This is ridiculous.
I mean, for crying out loud, your headlining video is a talk by a person who admits that he hasn't done the thing he's trying to convince people to do.
He says things like this:
"You don't want to wait for the market to take care of this, you would like to take some proactive steps to be able to make more of the people who should be using C++ willing to use it."
in the context of aerospace, which clearly he has no authority to speak on, since he misses one of the fundamental reasons why C++ is not popular or even acceptable in much of aerospace: implicit allocation. Implicit allocation is incredibly dangerous for high assurance systems. You really need to know exactly how much memory can be allocated, when, and what state the exact allocations will put the allocator in. C++ has some facilities to manage this, but man, it is easy to drop a plane from the sky by assuming that your allocation did what you wanted instead of verifying it.
But according to TFA, people who prefer C are just being emotional and irrational.
[0] Scott Meyers. Things that Matter - DConf2017 [@27:51] (https://youtu.be/RT46MpK39rQ?t=27m51s)
With C++ it easier to express higher level concepts. I can have a map of strings to some class instance. Then I can use some string to lookup class instances. There are simple idiomatic ways to do this. They are short to writes (<10 lines), they will have decent performance and will be low on bugs and clear ownership semantics.
With C it is common to have an array of pointer to pointer to void pointers. To get associative lookup it might be even worse and have functions that need to pointer to pointers, with who knows what ownership model and what idioms in use.
I could talk to my perl programming colleagues for days about the advantages of python over perl, but what got them to switch was boto, since we were moving to aws.
In this situation, C is a much better choice because most other languages have nice interoperability with C, but seldom, if ever, with C++. For example, as an iOS developer I can use C and C-libraries very easy with Swift, while inter opt with C++ is not possible at all and probably never will.
The main thing keeping me away from C++ is that it does not have a stable common ABI. This makes it very nearly impossible to use C++ to create and distribute a shared library. I even believe Google developers internally are prohibited from creating C++ libraries for this reason. So I'm sticking with C for low level stuff. It's a perfect glue language and fast. For higher level stuff, why use C++, when you can use Swift, Java, Haskell etc etc?
Because they themselves derived some benefit from it, and believe the other party would too, if only they would try it.
Sometimes, I don't think it's just benefits, but certain languages offer different ways of doing things that other languages really could benefit from. Our older languages teach us things as we use them, like that nullable pointers as our only reference type were a bad idea. Encouraging others to use languages that adopt different ideals would seem to be to just be people trying to get people to see the merits of those ideals.
> Why get into religious wars?
Because we're still using languages with nullable pointers. More seriously, because people care about the quality of their work, and you don't always get to pick the tool for the job. And it can very well be that there isn't a good tool for the job, but only and okay tool for the job: while I use Python extensively at my job, and while its speed of development definitely benefits my team, I would kill for some static typing. (I've been looking into mypy for this reason, but being on Python 3 would help…)
And people don't always use the right tool for the job, or I'd be done trying to explain why they should not be using raw bytestrings for text. They didn't pick the wrong tool for the job — they simply don't understand that actual string types exist, or why they should use them. (It doesn't help when the language/library's obvious choice is the wrong choice.)
I don't want to maintain a giant heap of buggy C Code.
I don't want to deal with bugs in the JVM/JNI.
I want ownership semantics expressed in code. When a C functions accepts or return a pointer who deletes it?
I want code to be easily tested, automatically. Common C code has so much shared mutable state that unit tests are rare, and when used are trumpeted as masterworks of engineering like the sqllite test suite.
C makes all these things hard or impossible to work with. From my perspective, the only positive it brings in the standardized ABI.