What are the fundamental differences between C and C++?
Many tend to write "C/C++", as if they were the same thing. Although they share many similarities, they are clearly not the same.
But what are really the fundamental differences between C and C++? Is C++ an enhanced version of C, or are there features in C which do not exist in C++?
@JoeDF It was at the very beginning but it's actually "compatible with C" now which don't mean the same thing at all. You don't code in C in C++ and not all standard C is compatible with standard C++.
The following points relate to C++:
- (user-defined) static type system: allows static checks about your data and their usage - points a lot of easily done errors in C.
- multi-"paradigm": allows working like in C, with object-oriented paradigms, with generic paradigms etc.
- Constructor/Destructor: the only way to say once what to do when creating or destroying something and be sure the user will not have to find the right function and use it like in C.
- RAII (badly named): you don't have to always manage memory. Just keep things in scope and use smart pointers describing your objects lifetime. Still can use raw pointers.
- Templates: better than macro, a real language to manipulate and generate types before the final compilation. Only lacks a type system (see Concepts in future C++ standards).
- Operator overloads: allows to describe operations in a simple syntactic manner and even to define embedded domain-specific languages inside your C++ code.
- Scoped names: namespaces, classes/struct, functions, etc. have simple rules to make sure names don't clash.
- Exception system: a way to propagate errors that is often better than return code. In fact, return code are good for domain-specific logical errors, because the application has to manage it. Exceptions are used for "hard" errors, things that make the following code just incorrect. It allows for catching errors higher in the call stack if possible, react to such exception (by logging or by fixing the state) and with RAII, if well used, it doesn't make the whole program wrong - if done well, again.
- The Standard Library: C has its own, but it's all "dynamic". The C++ standard library is almost (not IO streams) made of templates (containers and algorithms) that allows generating code only for what you use. Better: as the compiler has to generate code, it will know a lot about the context and will hapily apply a lot of optimizations without having to require the coder to obfuscate its code - thanks to templates and other things.
- const-correctness: The best way to make sure you don't change variables you shouldn't. Allows to specify read-only access to varaibles. And it is only checked at compile time so there is no runtime cost.
C++ was invented to manage complexity that C could not handle. For example, a common problem with C was that you could "run out of names for variables" (not to be taken literally of course) because there was no encapsulation, namespaces etc.
Also, C does not have exceptions, therefore error handling is very error prone, since it depends on the library user to always check return values of functions, whereas with exceptions, the library developer simply throws an exception that guarantees program flow will be halted.
C++ helps by having the constructor init objects which is automatically called by compiler. Unlike C structs which need to be initialized by the programmer (hence another error-prone area).
Lastly, there is a lot of other advantages touted by OOP, such as object reuse as well the generic programming based concepts, such as templates and generics which allow you to reuse source code,etc.
I like that you write about C++ constructor vs C structs, and that it is error-prone. I agree with that. But I don't like the Java way of using this in JavaBeans, that always uses an empty constructor and then set the member fields with setters. In my point of view, that is as error-prone as C structs. I would prefer to set my Java Objects only with the constructor. See my question on StackOverflow about this.
Oh, come on, who prevents you from using OOP with C? You can reuse objects and do anything, even exceptions. There is even a book about it, called OOP programming in C.
You CAN do OOP in nearly every programming language still in use, but it doesn't mean the language was designed for it. Take Lua for instance. While it technically allows OOP, it seems there's about fifty different ways of doing it, a cause of much headache.
In general, everything that exists in C is supported in C++. Obviously the opposite is absolutely false.
Simply speaking, C++ is object oriented (so, for examples, you have classes), C is not.
C++ has a boolean type C89 doesn't.
They are different languages. They just share most of the syntax.
This isn't strictly true. For example, C99 has the `long long` data type which isn't (yet) part of ISO C++.
Err... C++ is not only Object oriented : you can use object oriented paradigms with C++ because the language provide features for that, but it provide features for other paradigms too. You should mention that, it's really important, it changes everything. If it didn't, we'd all have switch to java...
There are many constructs in C that do not work in C++.
@klez: yes -- but it's still wrong. While ANSI did originally develop C89 (which didn't have a Boolean type), new development is now done by ISO, and ANSI accepts the ISO standard, so the current ANSI C standard is identical to the current ISO C standard (which does have a Boolean type).
Thanks for pointing out. I'm a standard-freak, so in fact this is important. Corrected.
C99 can also declare variable-length arrays on stack :) Not part of C++ standard AFAIK.
C99 has some features that standard C++ doesn't - restrict keyword, static array parameter, designated initializers, compound literals, flexible array member. C11 has more features not available in standard C++. C can be object oriented and even has some advantages over C++ OO features.
C99 has a few features that don't exist (at least in exactly the same form) in C++ (e.g., flexible array members, variable length arrays, etc.)
C99 also added a lot to the library that's not present in C++ 98/03 standard; most of this has been added to C++11 though.
In terms of basic orientation, C basically supports structured procedural programming. C++ supports that as well as object oriented programming, generic programming, and metaprogramming (carrying out arbitrary computation at compile time). With C++11, it adds a few bits and pieces that could at least be mistaken for functional programming support as well (e.g., lambda expressions). C++14 has added a few more, but most of them are really more convenience rather than any sort of major change in orientation.
Personally, I think that templates are the most significant feature that C++ adds to C.
Er, how about classes with inheritance? That's really hard work in C, whereas a lot of Templates can be done with preprocessor Macros.
Preprocessor macros are not type-safe; it's pure textual substitution, which also makes debugging harder. To get basic classes and inheritance to work is not a lot of work in C. + you get to make your own metaobject model instead of being stuck with whatever the language designer chose for you. See, for example, this paper: http://arxiv.org/abs/1003.2547
My vote would be destructors for the most significant feature C++ has over C (even over constructors because of their amazing cleanup capabilities).