Why C++ is vastly superior to C
warp.povusers.org
warp.povusers.org
I know I'm flinging links around a lot here, but, well, this is all well-covered ground.
The bitching about bad compile time errors has been mostly fixed in clang.
Then only _inconsistency_ (in the correct sense of the term) in C++ I am aware of is the unordered initialization of static objects. So if you have "class A { ... A () { } };" and have a "A foo;" declared somewhere with static linkage, it can be hard to pin down exactly _when_ that constructor will be called. It will be called before control is transferred to main, but you may want even finer control.
If you have noticed other inconsistencies I'd love to know.
Yes, IOW, it is a compiler problem, not a language problem. Because one particular compiler is horrible on error presentation doesn't mean that the language is bad.
> declared somewhere with static linkage, it can be hard to pin down exactly _when_ that constructor will be called.
The language doesn't define it on purpose. The language leaves it to be defined by the implementation because it goes a little beyond the purpose of the compiler. The compiler transforms C++ source into object code. You can have multiple objects linked together into a single binary, and this linkage is very platform and operating-system dependent. C++ is already horribly difficult to implement correctly; if the language were to define an order for static initialization, it would be stepping on the operating system domain, and make it even more difficult to implement on some systems.
Consider this program:
#include <iostream>
using std::cout;
using std::endl;
struct C {
int x;
C(int _x) : x(_x) {}
operator bool() const { return 0 != x; }
};
struct D {
float f;
D(float _f) : f(_f) {}
operator bool() const { return 0.0f != f; }
};
int main() {
C c(9);
D d(2.0f);
if (c == d) {
cout << "Equal" << endl;
}
return 0;
}
g++ 3.4.4 doesn't so much as warn that something is fishy here, even with -Wall.Not only that, but c and d are considered to be equal.
I don't have a C++0x compiler handy, or I would test it, but I do believe explicit is only meant for cases such as this:
a + 1;
where a has a bool() operator that returns 1 or 0, in the old mode if there was no way to get a to be a number it would look at the operator bool() see that it returns a number and use that. Using explicit on the bool() operator would make that illegal and most likely a compiler error.
c.bool() == d.bool()
In this case both will return true since they are non-zero, and thus the statement would be
1 == 1
Which is true; the compiler did exactly as you told it to do.
Are you saying that the funtion YOU wrote to convert C/D to a bool shouldn't be invoked when YOU are using C/D as booleans?
But it's confusing that they're being used as booleans at all. They're converted because it will let the types match even though the conversion doesn't make much sense.
another provblem arises due to the decoration, mangling of c++ symbols (while c externs do not have this problem), and sometimes this is problem even with two different versions of the same line of compiler
another one is the runtime incompabilities (exceptions again) and different compilers.
this problem is so bitchy, that if you have to develop plugin for maya, motion builder in c++, you have to use the same compiler the products were compiled with, which is not the case for a lot of the infrastructure, os out there...
For some things, C++ is better than C. For some things Lisp is better than either, and for yet other things, Python is better than them all.
Why are people so insistent on declaring their view is absolutely right, with no arguments, everyone else is wrong, and that one language will rule them all?
Trust me. For some things I do, C is vastly superior to C++, but I'm not going to try to convince everyone that C is better than C++ (or anything else) for everything that anyone wants to do.
That would just make me look stupid.
This article is more "why C++ makes this particular program easier to write" and is in no way any proof that C++ is better than C.
If you have an example of C being a better fit for a problem than C++, feel free to share it.
http://warp.povusers.org/OpenLetters/ResponseToTorvalds.html
Things like: How many people is on the team who have to work on the code? How big is the turnover among the developers? How experienced are they? How long is the code going to live? Will some people have to jump in and fix bugs in the code on short notice?
For example, I have noticed that I prefer a nice clean dynamic language like Python when I know I am only person on the project. But in cases where I had to work on and improve code of a dubious quality, I much prefer it to be in C#, since type analysis makes it a lot easier to figure things out and refactoring in a safer way.
To put it another way: I like to work with nice clean code in Python or Haskell, but when I have to work with bad code, I prefer to work with bad C# code.
Comparing C or C++ to Ruby or LISP is stupid.
But comparing C or C++ to C# isn't completely off the mark. And comparing C# to Java isn't crazy either. And once you're at Java, there are plenty of cases where a comparison to Ruby or Lisp makes sense.
So anytime a use case starts in Java (web, mobile, and desktop applications), I think there are very good comparisons to be had on which direction to go.
It depends on what you are working on, the libraries and tools available, and your comfort with what languages fit that paradigm.
I use C++ and Java on a regular basis now, but prefer C for systems programming, and Python for general web/scripting stuff.
Since we need to have a nit with C++ for this thread, can someone explain to me how debugging in C++ while using templates is superior?
There's a great post by Linus Torvalds about C vs. C++ in the kernel. Some excerpts:
"My point being, that C++ adds absolutely nothing interesting."
"C++ is a mess. There's no design. It's just "add crud on top of C". And the crud isn't even meaningful, much less does it have a design. It's totally and utterly random.
It started out random, now it's randomness that gets added to by a committee."
Whole thing: http://www.realworldtech.com/forums/index.cfm?action=detail&...
http://warp.povusers.org/OpenLetters/ResponseToTorvalds.html
As someone who had substantial exposure to interviewing and hiring C and C++ programmers to add to a team of 250 it was bloody obvious that a lot of pure C++ programmers are the pompous know-it-alls who think they know C++, while C people are those with far more realistic self-assessment who actually do know the language. Linus got it absolutely right.
That said, when I'm working at the application level, C++ is better at a lot of things.
Finally, my cow-orkers and I have an agreement that if any of us start doing template metaprogramming, that that person will be shot.
Unfortunately, different programmers end up with different subsets.
I'd like to see some de facto standardization on subsets. For instance, there could be Basic C++. When programming Basic C++ you use it like C with the following C++ features added: constructors, destructors, references, std::string, and maybe the STL collections.
Simple Object C++ could be Basic C++ plus single inheritance.
The on top of that, we could add things like multiple inheritance, operator overloading, templates, and so on.
Google does, for one thing.
Without discipline both C and C++ will blow you up completely. With some discipline both the languages are manageable, and C++ more so; which is what the OP points out.
coding guidelines are also to include programming idioms, primitives, to use and build the solution around it.
for c++, c and others i wrote many of guidelines, and seeing the benefit later i can say the above.
Sometimes I need to map a string to a list of numbers. std::map<std::string, std::vector<int> >. Done. All memory allocation taken care of for you as well - nothing to leak. In C, how do you get by? You either have to reinvent a red-black tree each time you want that, or use some kind of type-unsafe macro horror, or just not use that data structure.
That seems to be a significant point of the article as well. Any C programmers care to enlighten me on this? Nowadays I couldn't code for long in C without thinking "screw this, I want a vector" and going back to C++.
Crude example: http://kernelnewbies.org/FAQ/LinkedLists
void foo()
{
Matrix *a = new Matrix(1000, 1000);
Matrix *b = new Matrix(1000, 1000);
delete b;
delete a;
}
Pretending exceptions solve error handling gets you a big fat zero. Look at boost: despite being written by C++ experts and held up as an excellent library (which it is!), it contains exception-unsafe portions. Why? Total exception safety is just as hard as the original error handling problem. void foo()
{
typedef std::auto_ptr<Matrix> matAP;
matAP a(new Matrix(1000, 1000));
matAP b(new Matrix(1000, 1000));
}C++ in general values performance over safety almost everywhere (just like C). That's probably why they made certain parts exception-unsafe.
If I need to something higher level there are plenty of choices of that already, and C is a great language for extending applications done in a higher level language.
I think that the author has some good points. but I think both languages have the places where they excel.
To say that one is "vastly superior" to the other is a mistake. If C++ was really "vastly superior" to C then why are so many people still using C and using it productively?
Why are so many people using Java (perhaps even more than C and C++ combined)? Does it make a good language? Absolutely not. In the case of such simplistic languages as C and Java, it's their simplicity that makes them a popular choice.
Productivity: I am not sure all the C folks are as productive as they could've been if they switched to C++. Same people.
The complexity of C++ is not only in the amount of new concepts compared to C, it is also in greater risks of producing bloated binaries. Too much knowledge and caution is required to keep C++ code maintainable in this regard. That's a drawback, but if you ask me, I'd never give up RAII, implicit destruction and exceptions for C; I'd rather understand them better in order to use them properly.
And finally, the article would look much nicer without the insults closer to the end.
I'm pretty sure that C folks are much more productive using C than C++. Hating the tools you are using tends to lower productivity to a halt.
Well, one contributing factor is that a lot of universities now have a heavily Java based curriculum (turning their CS programs into vocational schools, but I digress).
Another contributing factor is that Java has managed to carve itself a niche in which it is used extensively ("enterprise" applications - with all of the wonderful ambiguity that the word "enterprise" carries nowadays).
One more thing in Java's favor is just simple momentum. There are a lot of Java libraries that just plain work (and some work extremely well). There are a lot of applications on the corporate side that use Java.
Regardless of whether you or I like the language or not, Java has apparently proven itself useful to a broad swathe of people. It may not be an exciting language, but then neither is Cobol and it still exists as well (and puts food on quite a few tables).
Then there is the venerable JVM, which is actually an amazing piece of software engineering that has enabled the development of a wave of innovative new languages. Of course, one of the features of many of these new languages is the ability to drop down into Java for speed (now before anyone starts sneering, Java is actually not doing to bad on that front right now).
"Does it make a good language? Absolutely not."
Perhaps not in your opinion, but their are others who are quite fond of it. That's the problem with these type of pronouncements. What makes a "good language" varies from person to person.
Disclaimer: I have used Java for some small projects in the past - I may be somewhat biased.
Edit: Embarrassing grammatical flaws.
What we call a matter of preference is actually things that go beyond engineering. We may have emotional ties to programming languages ("I love Java", "I hate C++") because of job security, because of often subconscious fear of inability to learn new stuff, and so on. We should clean up the table from the psychological aspects of the matter and look at what's left: that's how powerful and how clever a language can be in the hands of a good developer.
Java is a terribly verbose and an embarrassingly simplistic language. C is simplistic and can be considered dead the day C++ compilers catch up with speed and memory allocation, which will make it suitable for embedded programming too.
(And BTW, I don't mind JVM, it probably is a fantastic piece of engineering, except... for reasons I don't understand very well, a simple "Hello world" application written for JVM can take seconds to load and execute. I've heard a thousands reasons none of which made much sense. As well as promises JVM will be improved in the future. First time I heard this was 15 years ago, still no progress.)
You know what. It's a funny thing, but as I was typing my response to your original post, I actually said this exact same thing to myself, and I started to think. It would be incredible if there was some non-emotional, non-touchy-feely way to get at the value of one language vs another. But then programming language choice just seems to be an inherently "feel" based decision...
"We should clean up the table from the psychological aspects of the matter and look at what's left: that's how powerful and how clever a language can be in the hands of a good developer."
This is one of the things that I thought of, but then there are so many demonstrations of people using all kinds of programming languages to do things that are incredibly clever and powerful.
Sometimes I like to just go through open source projects written in programming languages I am not extremely familiar with. I just want to get a taste of some of the myriad of programming styles and techniques that are out there. The different ways of looking at the same problem.
Even if I disagree with the method used, it is always eye-opening to see other ways of doing things - even some that may be vastly different from anything that I have ever seen before (my first time looking at Haskell comes to mind). I like to understand how and why different developers choose the routes that they choose.
I don't know, but to me it seems that, in a way, it is good that there is no emotionless method for rating languages. To declare one language as being definitively better than all others seems to me that it would be a tremendous loss. There is some value, I think, in having a diversity of "good" languages just for its own sake.
As to the simplicity of a language, well, to some people simplicity in a programming language is a beautiful thing, but then, the problem is that what constitutes simple is also a thing that varies from developer to developer. Perhaps the diversity of languages is a natural development from the diversity of programmers?
I think about Ruby. You know, when Matz describes why he created the language, he says that he wanted to create something that felt fun to develop in - fun for him. The fact that other people just happened to like Ruby was an unintended side effect.
I think that most people create a programming language with a similar type of outlook. They, either purposefully or subconsciously, try to build it to achieve a certain "feel". Perhaps it is this "feel" that makes a good developer powerful and clever with a language.
"for reasons I don't understand very well, a simple \"Hello world\" application written for JVM can take seconds to load and execute."
Heh heh, I have no comments on that.
From this point of view, languages that are neither complex nor allow for complexity can be called "simplistic". They are easy to learn, easy to write code in, and as easy to grow to unmaintainable sizes because of their verbosity. Since we have very few readers here at the bottom of the thread, I will admit that every time I see all kinds of dancing around class instantiation, endless method calls etc in Java, where in some other language it would take a single function call, it reminds me of how kids count the steps out loud when they go up or down the stairs. When you grow older, you don't count any more, it's kind of implied :)
And I haven't found a better measure of quality of programming languages than that proposed by Paul Graham here: http://www.paulgraham.com/power.html
Edit: just noticed downvotes for my previous comment, so no, we are not alone :)
He doesn't pretend to have all of the answers but rather invites the reader to embark on a thought exercise. Ignoring the question of comparing languages, that is an excellent example of how to write concerning this type of topic.
On comparing languages, I have to say that comparing languages based on power does make sense - with power defined as programmer productivity. From this perspective, I can understand your view on Java.
But is it the language itself that is to blame or the spaghetti code that all too often results from inexperienced users? I recall that the JRuby team has done some interesting things within the limitations of the Java language.
Note: To those who down-voted the original comment, I did not think that the down-voting is the most optimum solution for when you have a different perspective on an issue. Wouldn't it be better for everyone to chime into the discussion and increase everyone's knowledge with your perspective on the issue? This type of thing is why I have to ignore votes and just try to learn.
Those really are not the problems that are most pressing with C++ in the embedded field. Comparable speed is rarely noticeably different provided you avoid certain key things, and you can always just swap in a new allocator if you want.
I once switched from C++ to C because g++ just couldn't handle the module even having all optimizations turned off. That was a huge automatically generated C module with thousands of functions. A rather rare situation but showed very clearly that C++ is not almighty.
No, for the very real issues with C++ in small installations, you will have to look at the language itself.
typedef struct { void *elements; int elem_size; int n; } Vector;
Vector *vector_new(int elem_size);
void vector_free(Vector *v);
void vector_push(Vector *v, void *elem);
void vector_pop(Vector *v);
int vector_size(Vector *v);
void *vector_at(Vector *v, int i);
etc. This is off the top of my head, but you get the idea. You can basically put anything you want in there as long as you say how large the elements are upon initialization.There is a good book on generic C programming: http://sites.google.com/site/cinterfacesimplementations/
*(int *)vector_expand(v) = 2;We'll just have to agree to disagree that what you've shown above is an acceptable API for a vector module.
The problem is that this library forced everyone to use it's types, interfaces, etc. - so the effect was spreading everywhere. Instead you should only do such things isolated, and provie "c" interface (for example zeromq does that).
Also do not propagate exceptions to client, especially if you are some middleware not used for the core of the things (for example social service api, advertisement api, or anything small used just as service).
Better do exceptions internally, and provide error codes or callbacks for client. Exceptions do not work on certain very popular gaming devices for examlple, and the user of your library might want to avoid them for other reasons
so do your best C++ in secret, if you want, provide us C interface
- There are some very good cross-platform toolkits available for C++ (such as Qt).
- There is no C99 support in Visual Studio. At the same time, C++-98 works across all major compilers these days.
- STL containers.
However, C++ just is the best choice for the projects I am currently working on. For other projects, with fewer dependencies and no portability requirements beyond Unixy environments I prefer C.
Nearly any language can be superior, depending on the project. The linked article attempts to show that C++ is superior based on some specific situations where this may indeed be the case.
None of the examples he showed of C code look like they were actually written by a C programmer. A lot of use of "goto"'s, for one thing. It looks like he tried reimplementing C++ in C.
Actually, that's exactly what he decided must be done: " If the C version wishes to match the C++ version in speed and memory usage, it will have to basically simulate the C++ implementation using a struct and functions which handle objects of that struct type (including things like initialization and destruction)."
So obviously, if you set out from the start with the assumption that to use a language, you have to reimplement another language in it, then of course you'll come to the conclusion that you should just use the other language. But that's not a conclusion that C programmers would be comfortable with.
By the way, as just one nitpick, I'd probably implement that Matrix with "void *" pointers, letting me substitute any struct I want in there later. Just my way of solving the "impossible to solve" problem he presents at the end.
Also I do not buy the argument that you do not have to follow coding conventions in C++ or that explicitly freeing memory is a bad thing. Also comparing the number of lines of code to determine the "best" language is childish. By that logic the language with the largest std. lib is the best.
If I were to defend C, I'd rather choose macros combined with plain typeless buffers. The choice between C and C++ in such cases is really a choice between the nightmare of wrong memory operations and total type unsafety on the one hand (C), and the nightmare of ineffective, bloated code on the other (C++). I believe the latter can be taken under control though.
You can say that C++ is vastly more powerful (and flexible) than C, but for low-level/embedded/kernel etc development, many would argue that C is the superior language.
Many people would also argue that C++ is maybe too powerful and complex; you can do everything with it, but sometimes this makes it hard to decide how to do "anything" (procedural ? Object-oriented ? Using templates ?).
Lots of people (myself included) find it so complex that they only use a subset of it - "the good parts". However, agreeing which parts to use is often impossible.
I've written about about what I consider "the good parts" here:
Personally I think the advantages boil down to syntax and type-safety. For example, vector math is much more succinct and can be made type-safe. Constructors/destructors also can be handy for enforcing resource allocation.
We could name a restricted subset of C++ as C+-. Many high quality and well-tested development tools for C+- already exist (the C++ tools). Now the problem remains of standardizing C+-. The most logical C+- variant to standardize on is the C++ subset used by the largest group of people, presumably the version defined by Google: http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
Now the question becomes is it easier for average programmers to build application programs using C or C+-? Using C+- or C? These are perhaps more useful questions than the long running C vs C++ debate.
Yea right. This guy is full of it. This article is very biased...
The flip side of that coin is that if you don't know what you're doing, you can blow off your leg, your friend's leg, and the legs of everyone in a twenty-foot radius.
$ cat > foo.c
#include <stdio.h>
int main(int argc, char**argv){
puts("hello world");
return 0;
}
^D
$ cat > foo.cxx
#include <iostream>
int main(int argc, char**argv){
std::cout << "hello world" << std::endl;
return 0;
}
^D
$ time gcc -o hello-c foo.c
real 0m0.039s
user 0m0.020s
sys 0m0.012s
$ time g++ -o hello-c++ foo.cxx
real 0m0.182s
user 0m0.144s
sys 0m0.028sCompilation of C++ is really surprisingly slow. Mostly because compilation of modern C++ code involves parsing tens of megabytes of headers that mostly use complex to analyze constructs. Fact that C++'s grammar and semantics are incredibly complex does not help fast compilation either.
Separate compilation does not solve it much, because many simple changes, that affects only one file in other languages, force you to recompile significant subset of your codebase.
While you may save time coding I don't believe that debugging C++ code is in way easier than C code, I think it is quite the reverse. While you mostly eliminate some problems by using C++ you get whole lot of other C++ specific problems (static initializers, unexpected effects of overload resolution, unexpected effects of automatically generated code, weird performance characteristics...).
Most of this can be worked around, but in that cases you end up using subset of C++ that could be more flexibly implemented on top of C as few hundred lines of preprocessor macros and some coding conventions than by it's own compiler.
There's definitely something to what you're saying here. Or, rather, maybe something a few years ago. However, I don't think it really applies so much in 2011. Computers have gotten big and fast to the point where this argument is pretty meaningless.
Personally, I stopped caring about compilation time when I got a 3.6GHz i7 with eight in-flight threads. I'm OK with feeding the beast on this one--what I get from C++ is defnitely worth it. (Debugging isn't particularly difficult, I find - you end up using a subset of C++, but there's no way in hell you could implement my subset of C++ in C and not hate working with it.)
Often you'll see a C++ basher bring up compilation speed and then in the same thread advocate python + C as the happy medium, which I find crazy. C++ is so much higher level than C the need for scripting is often obviated. I've typically got about 2x SLOC expansion rewriting perl/python as C++, including stuff like headers, so really not much more code at all, just 100x faster and a tiny fraction the memory.
The other line you see, including elsewhere on this page right now, is that C and C++ are the right tool for the job in different domains. I really don't get this. C++ is straight-up a replacement for C. There is no C program that wouldn't be shorter and clearer rewritten as C++. The only occasion to not use C++ is when you don't have compiler support, which is extremely rarely a concern anymore. Even the lowest level embedded stuff is moving away from C in favor of C++.
Also, I believe the rule of thumb for the -j argument tends to be 2 times your number of cores. A surprising amount of build time is often spent on disk I/O, so you see worthwhile gains for quite a while running more jobs than cores.
It's just too goddamn easy to make a mess in C++ without noticing it. In C, if you make a mess, you will more likely notice it before it's unmanageable.
I have a counter example (assuming I've understood you):
/* C /
int foo () { FILE x = fopen("bar"); return 0; }
/* C++ */ int foo () { ifstream in("bar"); return 0; }
[1] http://harmful.cat-v.org/software/c++/I_did_it_for_you_all