Since C++ seems to have all of C's features, why learn C over C++?
C++ is basicly C with some new features, such as classes for instance. If you are new to programming you should concider learning C first. You shouldn't be able to dig too deep down before you know the foundations.
- C requires less runtime support (useful in low-level environments, such as embedded systems or OS components)
- C is compiled faster ;-)
There are many situations that C is still useful. First, it has probably the biggest code page available. Many open source projects (os kernels, toolkits, web servers, http clients) are written in C. I don't think that these are going to be ported in another language soon. So if you want to be a contributor to a major open source project, you need to know C well. The same applies if you need to support legacy code.
C is also mainly used in embedded software projects. Micro-controllers have limited resources and C is better suited for them than C++. Most device drivers are also developed in C.
One reason you might program in C is if you intend to read the generated assembly code. C++ does name-mangling, generates virtual tables for classes that use virtual functions, and other such things that will make the resulting assembly code harder to read (although I'm sure that doesn't scare some programmers). I'm a bit of an assembly noob and I sometimes write C code just to see what kind of assembly the compiler generates for the purpose of learning. This can also be a good way to research optimization strategies, for instance.
Another reason to stick with C is if you have a project or team where the advanced features of C++ are seen as a risk. Perhaps the project has a very straight-forward design and you don't want there to be any excuse for team members to get fancy with a complicated class hierarchy (this is more of a team management problem than a real tech problem, obviously). The decision to go with C may force project members to approach the problem in a simple way, although one hopes that such management trickery would never be needed in the first place.
Simucal made good comment on the above point in one of the other answers: "I know that the decision to code Git in C vs C++ was partly due to that. Linus was raving about the number of "bad" c++ programmers and how using C instead, he was keeping a huge amount of poor developers out." (link added)
Yet another reason I can think of to go with C is if you need to write a compiler for your target platform because there isn't a suitable one available. This is highly hypothetical, but if I found myself in a position of trying to bootstrap a software development pipeline for a hardware platform without existing compiler tools, I'd start by writing a C compiler because it's far easier to do so than to write, say, a C++ compiler.
One reason to learn C (but not necessarily use it) is to gain insight into the roots of programming. C was an extremely influential language that helped shape Unix culture as well as all of modern computer technology. One can better understand the design of C++, Unix, and even how assembly code works by having a detailed knowledge of C. It's yet another important puzzle piece in understanding how computer technology all fits together.
- C is much easier to learn then c++
- C is slightly easier to master then c++
- C has a wider support of processors then c++
- it is easy to shoot yourself in the foot with both, but c++ has more class
- you would learn c as part of your c++ studies anyway.
There is none. Even if you don't use the whole C++ feature set C++ still offers some substential advantages over C. This is why some of the other arguments mentioned here fall short of reality:
C is compiled faster
For normal code this is definitely true. C++ does some really wacky stuff at compile time which, unfortunately, is time-consuming. However, if compile time really matters, you're able to write code that compiles just as fast as equivalent C code.
C requires less runtime support (useful in low-level environments, such as embedded systems or OS components)
Also true. However, there are special stripped-down versions of the C++ runtime for embedded systems. Again, this drastically diminishes C++' advantage over C but it still has advantages!
First, [C] has probably the biggest code page available.
Not an argument, since all of this code can be directly used from C++. However, this is obviously true:
So if you want to be a contributor to a major open source project, you need to know C well.
So yes, in such a situation it really pays to know C. Another reason are the aforementioned embedded systems. While there are C++ compilers for some of them, this is not true for all environments and sometimes it's simply a cost factor that speaks against bootstrapping a C++ compiler to work here. Generally, if no specialized compiler for a given platform exists, don't use C++ there.
However, I would still strongly advise first learning C++ and then "downgrading" to C because C++ is much easier to learn. I've talked about the reasons before.
- Simplicity
- Portability
- Maintainability
- Interfacing to Scripting Languages
In all this areas C has an advantage over C++. C is a very matured language and backward compatability was always very high on the list. One can say just with ANSI C 99 this has changed, because then some new things were introduced (e.g complex numbers) before they were in widespread use.This has let to the situation that, people do not use some of the ANSI C99 stuff because their compiler does not support them. But one still can even compile K&R C with the current C compilers. Maybe in the COBOL or FORTRAN world something comparable can be observed...
You might also find this thread interesting:
http://stackoverflow.com/questions/211686/what-do-you-miss-when-you-have-to-use-c-instead-of-c
what is the gain then
constraining self by forms that
limit expression?
Linus Torvalds has a pretty strong opinion on the matter.
He was asked the following concerning his Git version control system:
When I first looked at Git source code [it] struck me as odd: Pure C as opposed to C++. No idea why. Please don't talk about portability, it's BS.
His reponse is pretty entertaining:
C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do nothing but keep the C++ programmers out, that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles Bader jokingly said "to piss you off", but it's actually true. 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.
C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:
infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny)
inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app.
In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C. And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap.
So I'm sorry, but for something like git, where efficiency was a primary objective, the "advantages" of C++ is just a huge mistake. The fact that we also piss off people who cannot see that is just a big additional advantage.
If you want a VCS that is written in C++, go play with Monotone. Really. They use a "real database". They use "nice object-oriented libraries". They use "nice C++ abstractions". And quite frankly, as a result of all these design decisions that sound so appealing to some CS people, the end result is a horrible and unmaintainable mess.
One very good reason is that C has a de facto standard ABI on most platforms, while C++ doesn't.
Portability has been mentioned before but it has not been stressed enough. Something written in C89 (ANSI 1989 Standard) is EXTREMELY PORTABLE, it is literally referred to as portable assembly. If portability is your key concern, C89 is the way to go. Nothing, I mean nothing is more easy to port than something written in C89. Rest assured that you will find a C89 compiler for almost any hardware.
C is a much smaller language with fewer but extremely stable functionality. - It has many flaws, however these flaws are widely known. - The flaws in C can easily be managed through the use of conventions, guidelines and recommended libraries, some of which can be specified by the project. - It is widely supported, and is much the same everywhere you go.
In addition, because C is much smaller, it is also much simpler - yes, you do have to deal with pointers and low level detail, however good programming practice in C is to use functional decomposition to abstract these details wherever possible.
Naive or unskilled programmers can easily be knocked about and forced to conform to the project because the guidelines needed are very small.
In C++, however, it is a huge language that is constantly evolving, functionality that should've been avoided in projects 5 years ago should be recommended today, and vice versa. It has functionality that can be used one platform, but can not be used on another, and the style of C++ is a topic that has yet to mature.
Caveats: - my usage of 'smaller', 'widely', 'much the same', 'everywhere', 'huge' are all relative terms, not absolute. - I'm a C++ fan, and love the language - Simplicity, however, is not in C++'s lingo, although it has been said that within C++, there's a smaller, simpler language struggling to emerge.
Two quick points:
- Embedded systems come to mind, C is less resource-hungry
- Portability is also a point as C compilers are more easily ported
But for larger systems, I tend to go with C++ over C almost all the time.
Almost all high performance stuff. There is also COBOL which is highly recommended for processing high amount of data. Probably your phone bill is printed by a mainframe running a COBOL program.
C is more portable and faster than C++.
Many embedded projects will probably use C.
GIT is written in C, linus hates c++.
The performance differences between compiled C and compiled C++ are very minor (but sometimes relevant nevertheless). It's largely a stylistic choice (with profound consequences to your software design mind you) although on some more arcane platforms you may find easier access to C compilers than C++ compilers (although gcc is almost ubiquitous these days).
Some have strong opinions about this. Linus Torvalds famously ranted against C++:
C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do nothing but keep the C++ programmers out, that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles Bader jokingly said "to piss you off", but it's actually true. 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.
C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:
infinite amounts of pain when they don't work (and anybody who tells me
that STL and especially Boost are stable and portable is just so full
of BS that it's not even funny)inefficient abstracted programming models where two years down the road
you notice that some abstraction wasn't very efficient, but now all
your code depends on all the nice object models around it, and you
cannot fix it without rewriting your app.In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C. And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap.
So to answer your question any project where performance really mattters is suitable to written in C if you're so inclined.
C is also a language whose specification can (more or less) be described in detail in a fairly slim volume. When I meet a competent C programmer, I can be reasonably sure that she or he is familiar with 90% (or more) of the features of the language.
Compare and contrast to C++, where I'd guess that a large number of people developing in it don't even know about, much less use, a huge percentage of the language features. On the one hand, that means the language has lots of power and flexibility. On the other hand, it means that for any given C++ project there's more likely to be code that's going to be using some feature that a nontrivial number of developers have no idea how to use.
It's hard to overrate simplicity.
Some have asked for a real-life project written in C and C++.
TrustLeap G-WAN is a Web Application Server which is faster (in user-mode) than IIS 7.0 (in the kernel). G-WAN ANSI C89 ('edit & play') scripts are 5x faster than ASP.Net C#.
G-WAN is up to 38x faster than Apache. G-WAN is up to 25x faster than Nginx.
G-WAN was started in C++ and then converted to C because of the '++' overhead. The gain was not only in footprint (currently 106 KB), but also in performances (~180%).
If you want to know what makes C++ so bad, just try virtual inheritance and virtual functions, and then compare the machine code générated by the C++ compiler with a clean C implementation of the same features (the C++ code is twice larger -and slower).
Conclusion: if you are targeting performances then you can use C++ as long as you write C code compiled with a C++ compiler.
In my humble opinion, Linus is a programmer that make systems work, and Bjarne is a programmer that uses the systems created by programmers like Linus.
There should be no surprise that system users are less technically inclined than system engineers.
Best I remember, if you want to develop device drivers on Windows you had to use C. The dev kit didn't support C++. (This may have changed.)
Some other answers have mentioned that C is good for embedded programming because resources are limited. One reason why C is better in embedded environments is because you have a better sense of memory usage by data structures. When a C++ class get instantiated, it's hard to tell how large that object will be because of inheritance. This problem can be mitigated by limiting class hierarchies to be only a few deep. C++ templates also cause a similar problem. Heavy usage of templates can really increase the footprint of the executable. Just because these features aren't in C doesn't mean that you won't get similar memory problems. But, if you do, it's a little easier to track down where memory is being used.
Jacinto,
If only Bjarne had done something that made sense, my comment would have been less severe.
But C++ is "not a better C", it's a drama -and Bjarne himself has several times recognized it:
- Pierre.
There are certain cases where it makes sense to use C, such as writing device drivers or kernel modules. A lot of people argue that C's simpler feature-set leads to a much simpler, maintainable code base. But honestly, I get the opposite impression when it comes to large projects. I simply can't imagine writing a large project (>100K lines of code) in straight C these days.
If you actually spend time reading a lot of C source code, especially for large projects, you invariably find that one way or another the designers end up reimplementing C++ features such as virtual functions, inheritance, templates, etc., using wacky macro tricks, function pointers, preprocessor token concatenation or what have you. The fact is, its simply harder to reuse code in C because you don't have the facilities of object-oriented or generic programming at hand, and so you either have to copy and paste code, or use macro tricks to emulate these facilities. To say that this is more maintainable than modern C++ code is insane.
And, just to piss off the OOPs:
C has better support for encapsulation.
C++:
/* foo.hpp: */
class Foo
{
private:
int not_part_of_the_api;
public:
int getint();
}
/* foo.cpp: */
Foo::getint()
{
return not_part_of_the_api;
}
C:
/* foo.h: */
typedef struct foo Foo;
int foo_getint(Foo*);
/* foo.c */
struct foo
{
int not_part_of_the_api;
};
int foo_getint(Foo* self)
{
return self->not_part_of_the_api;
}
Which one do think will need the user to recompile if you change something that's not_part_of_the_api?
Here's a list of differences I documented a few years back, with a few additions:
C is an old byte processing language with
- No namespaces (no syntax grouping names, injecting names, or pulling out a custom overload when needed, causing the used operator/function to change without any additional code, all within the intended scope and for the intended identifier)
- No template metaprogramming (preprocess until you have to start debugging your preprocessor output)
- No operator/function overloading
- No generic containers
- No generic algorithms
- No RAII
- No exceptions (no automatic RAII cleanup via stack unrolling, needing manual cleanup code)
- No polymorphism
- No references
- No specialized casts (one cast does all, no intention documented, not easily searchable)
- No using keyword in class-context
- No allocators (no way to switch between debug-build memory allocation and release-build memory allocation with ease for any chosen type)
With the new C++0x features that are already supported by some implementation vendors,
- No generic reusable hashing component
- No atomicity support
- No Thread Support
- No lambda expressions