Learning C when you already know C++? - c++

I think I have an advanced knowledge of C++, and I'd like to learn C.
There are a lot of resources to help people going from C to C++, but I've not found anything useful to do the opposite of that.
Specifically:
Are there widely used general purpose libraries every C programmer should know about (like boost for C++) ?
What are the most important C idioms (like RAII for C++) ?
Should I learn C99 and use it, or stick to C89 ?
Any pitfalls/traps for a C++ developer ?
Anything else useful to know ?

There's a lot here already, so maybe this is just a minor addition but here's what I find to be the biggest differences.
Library:
I put this first, because this in my opinion this is the biggest difference in practice. The C standard library is very(!) sparse. It offers a bare minimum of services. For everything else you have to roll your own or find a library to use (and many people do). You have file I/O and some very basic string functions and math. For everything else you have to roll your own or find a library to use. I find I miss extended containers (especially maps) heavily when moving from C++ to C, but there are a lot of other ones.
Idioms:
Both languages have manual memory (resource) management, but C++ gives you some tools to hide the need. In C you will find yourself tracking resources by hand much more often, and you have to get used to that. Particular examples are arrays and strings (C++ vector and string save you a lot of work), smart pointers (you can't really do "smart pointers" as such in C. You can do reference counting, but you have to up and down the reference counts yourself, which is very error prone -- the reason smart pointers were added to C++ in the first place), and the lack of RAII generally which you will notice everywhere if you are used to the modern style of C++ programming.
You have to be explicit about construction and destruction. You can argue about the merits of flaws of this, but there's a lot more explicit code as a result.
Error handling. C++ exceptions can be tricky to get right so not everyone uses them, but if you do use them you will find you have to pay a lot of attention to how you do error notification. Needing to check for return values on all important calls (some would argue all calls) takes a lot of discipline and a lot of C code out there doesn't do it.
Strings (and arrays in general) don't carry their sizes around. You have to pass a lot of extra parameters in C to deal with this.
Without namespaces you have to manage your global namespace carefully.
There's no explicit tying of functions to types as there is with class in C++. You have to maintain a convention of prefixing everything you want associated with a type.
You will see a lot more macros. Macros are used in C in many places where C++ has language features to do the same, especially symbolic constants (C has enum but lots of older code uses #define instead), and for generics (where C++ uses templates).
Advice:
Consider finding an extended library for general use. Take a look at GLib or APR.
Even if you don't want a full library consider finding a map / dictionary / hashtable for general use. Also consider bundling up a bare bones "string" type that contains a size.
Get used to putting module or "class" prefixes on all public names. This is a little tedious but it will save you a lot of headaches.
Make heavy use of forward declaration to make types opaque. Where in C++ you might have private data in a header and rely on private is preventing access, in C you want to push implementation details into the source files as much as possible. (You actually want to do this in C++ too in my opinion, but C makes it easier, so more people do it.)
C++ reveals the implementation in the header, even though it technically hides it from access outside the class.
// C.hh
class C
{
public:
void method1();
int method2();
private:
int value1;
char * value2;
};
C pushes the 'class' definition into the source file. The header is all forward declarations.
// C.h
typedef struct C C; // forward declaration
void c_method1(C *);
int c_method2(C *);
// C.c
struct C
{
int value1;
char * value2;
};

Glib is a good starting point for modern C and gets you used to concepts like opaque types and semi-object orientation, which are common stylistically in modern C. On the other end of the spectrum standard POSIX APIs are kind of "classical" C.
The biggest gap in going from C++ to C isn't syntax, it's idiom and there, like C++, there are different schools of programming. You'll write fairly different C if you doing a device driver vs., say, an XML parser.

Q5. Anything else useful to know?
Buy a copy of K&R2 and read it through. On a cost per page basis it'll probably be the most expensive book on computing you'll ever buy with your own money but it will give you a deep appreciation for C and the thought processes that went into it. Doing the exercises will also hone your skills and get you used to what is available in the language as opposed to C++.

Taking your questions in order:
Unfortunately, there's nothing like Boost for C.
Nothing that's really on the order of RAII either.
The only compiler that tries to implement C99 is Comeau.
Lots of them all over the place, I'm afraid.
Quite a bit. C takes quite a different mindset than C.
Some of those may seem rather terse, but such is life. There are some good libraries for C, but no one place like Boost that they've been collected together or given a relatively uniform interface like Boost has done for C++.
There are lots of idioms, but many of them are in how you edit your code, such as sort of imitating RAII by writing an fopen() and a matching fclose() in quick succession, and only afterwards writing the code in between to process the data.
The pitfalls/traps that wait around every corner mostly stem from lack of dynamic data structures like string and vector, so you frequently have to write such things yourself. Without operator overloading, constructors, etc., it's considerably more difficult to make them really general purpose. Lots of libraries have them, but you end up rolling your own anyway because:the library doesn't do quite what you want, orusing the library is more work than it's worth.
The difference in mindset is almost certainly the biggest thing, at least for me. When I'm writing C++, I concentrate almost all my real effort on designing the cleanest possible interfaces, and I tend to treat the implementation of an interface as almost throwaway code. For the most part, I don't plan on making minor tweaks to that part of the code -- as long as the interface is good, replacing the entire implementation is usually easy enough that I don't worry about it much.
In C, it seems (at least to me) much more difficult to separate the interface from the implementation nearly as thoroughly or cleanly. As such, I tend to spend a lot more time trying to implement every part of the code as cleanly as possible, because later changes tend to be more difficult and throwing away and replacing pieces that aren't very good is substantially less likely to work out very well.
Edit (since people have raised questions about C99 support): While my statement about lack of C99 support may seem harsh, the fact is that it's true.
MS VC++: supports C95, and has a couple C99 features (e.g. C++ style comment delimiters), mostly because C99 standardized what they'd previously had as an extension.
Gnu: According to C99 Features Status page, the most recent iteration of gcc (4.4) has some C99 features, but some (including VLAs) are characterized as "broken", and others as "missing". Some of the missing "features" are really whole areas, not individual features.
PCC: The PCC site claims C99 conformance only as a goal for the future, not as a present reality.
Embarcadero Technologies (nee Borland) don't seem to say anything about conformance with C99 at all -- from the looks of things, the last time they worked on the C compiler may well have been before C99 was even released.
Microsoft openly states that they have no current plans for supporting C99, and they're not going to even consider it until VS 2010 is released. Though I can't find any public statements about it, Embarcadero appears about the same: no hint of a current plan, and nor even that they're going to consider working on it anytime soon.
While gcc and pcc both seem to have plans, they're currently just that: plans. They both openly admit that at the present time, they aren't really even very close to conforming with C99.

Here's a quick reference of some of the major things you'll want to know.

This is advice you didn't ask for: I think most potential employers take it as a given that if you C++ you know C. Learning the finer points of C, while an interesting academic exercise, will IMO not earn you a lot of eligibility points.
If you ever end up in a position of needing to do C, you'll catch on to the differences quickly enough.
But don't listen to me. I was too lazy and stupid to learn C++ :)

Anything else useful to know ?
C99 is not subset of c++ any revision, but separate language.

Just about the biggest shock I had when I went back to C was that variables are defined at the function level - i.e. you can't scope variables inside a block(if statement or for loop) inside a function.

Except for very few cases, any C code is valid C++, so there isn't actually anything new you should learn.
It's more a matter of unlearning.
Not using new, not using classes, defining variables at the beginning of a code block, etc.
In a strict sense, C++ is not object-oriented, but it's still procedural with support for classes. That said, you are actually using procedural programming in C++ already, the most shocking change will be not having classes, inheritance, polymorphism, etc.

As C++ is almost a superset of C89, you should know just about all of C89 already. You probably want to concentrate on the differences between C89 and C99.

Related

Using C++ API in C?

One day I decided to start writing a video game in plain old C.
It was a lot of fun, and three months later (I sometimes have little time away from the job) I found myself in the need of some physics engine.
I decided to use Bullet physics engine, because it seems like one of the better ones out there for what I need.
Then, I found out Bullet doesn't really have a C API but only a full C++ API. Its C API is not maintained.
After a day of cursing, I 'converted' my project into C++, which is a bold statement for saying I typecasted all heap allocation and I use new and delete instead of malloc and free, and wrapped up some definitions in 'extern "C" { ... }'.
Some people would probably shoot me for doing that, but I saw no other option to using a performance-tasking thing such as this physics engine, which only has a C++ API, in C.
So now, I'm compiling with g++, while still writing mostly "C" code.
I find myself a little less happy, because the code no longer feels as pure.
C++ gives me some strange error messages, while I have nothing against the language I often do not like the g++ parser.
Aside from the fact that I can now happily bounce objects into each other, some of the smallness and purity of my pet project has been deserted now.
I'm wondering if I did the right thing. Can I ask for some advice, should I just carry on and not worry about using a C++ compiler for my 'mostly' C code? Are there other ways to use this API in C without any performance hits or overdone maintenance work?
I'm wondering if I did the right
thing.
Well, you needed a component for your project, and instead of inventing it again from scratch, you reused an existing piece of software. It actually sounds right to me.
Can I ask for some advice, should I
just carry on and not worry about
using a C++ compiler for my 'mostly' C
code?
You don't need to worry at all. C++ is almost 100% C compatible. There are no penalties on doing that. You have actually earned better compile-time checkings due to a much stricter type system.
Are there other ways to use this API
in C without any performance hits or
overdone maintenance work?
No, you can't use the API in C without converting your code to C++. C++ identifiers are mangled: this means that, even if you were ready to use the C++ API from plain C, you wouldn't know how to refer to them. Theoretically this is possible, in practice it isn't.
Your way is the correct one.
Good luck with that game!
I think you're overly concerning yourself with things that aren't really problems. You say that some of the purity has gone. Well, I can understand this. You wrote it in C and then, realizing you had to use C++ to use an API of choice, shoehorned it in. Now it doesn't feel like your pet baby anymore. This is a subconscious issue, not a programming one.
I suggest you bite the bullet (haha), and rewrite your project in C++. Then it will be pure again, you'll learn a lot on the way, and won't feel like your C-child is being sodomized.
Depending on how tightly coupled the different subsystems of your engine are, it might be feasible to write different parts of the engine in different languages.
For example, you could factor out the physics part into a C++ module which exports a C API and let the rest of your application stay in C. However, it might make more sense to write the central part of the system in C++ and refactor your existing C code into seperate modules.
If you want to write your project in C, write it in C and make a C wrapper for the library; have a look at this question for some advice about it.
Otherwise, rewrite your project in C++; but please, don't write yet another C project with some C++ here and there, in my experience these projects can quickly become a mess (and if you write code with a C mindset but calling C++ code weird things start to happen when exceptions are added to the mix).
Don't worry about writing mostly C code and compiling it with C++. Just adopt using new/delete instead of malloc/free and you'll be fine. The advantage of using new is that you don't have to cast the result to the proper pointer type (implicit casts from void* to other pointers are disallowed in C++) and that new will never return an invalid pointer. You loose realloc() though. (And no, don't even think of mixing new/delete with realloc :))
The only reasons you would keep a project as "pure C" are either because of source code compatibility, tool support, or because of language standards (MISRA-C etc). "I want it to feel pure" is probably not a very rational argument.
If keeping the code as pure C for such reasons is important, your could have written a "wrapper" DLL (assuming Windows) in C++, which does all the communication with your 3rd party API. You'd get a fair bit of overhead of course.
The strange error messages are no doubt caused by the stricter typing in C++, which can be a bless or a curse depending on the situation. A C++ compiler will be more likely to slap your fingers when encountering dangerous implicit typecasts (integer promotions etc) and it will likely enforce stricter "const correctness". But at the same time, it will moan about void pointers, which are considered good generic programming in C, but dangerous, sloppy and possibly redundant in C++.
One option is to convert the C++ code to C using LLVM. See this FAQ from the project's website: Can I convert C++ code to C code?

C or C++ to write a compiler?

I want to write a compiler for a custom markup language, I want to get optimum performance and I also want to have a good scalable design.
Multi-paradigm programming language (C++) is more suitable to implement modern design patterns, but I think that will degrade performance a little bit (think of RTTI for example) which more or less might make C a better choice.
I wonder what is the best language (C, C++ or even objective C) if someone wants to create a modern compiler (in the sense of complying to modern software engineering principles as a software) that is fast, efficient, and well designed.
The "expensive" features of C++ (e.g., exceptions, virtual functions, RTTI) simply don't exist in C. By the time you simulate them in C, you're likely to end up with something at least as expensive as it is in C++, but less known, less documented, etc. (let's face it: compiler writers aren't stupid -- while it's possible you can implement a feature "better" than them, it's not really particularly likely).
In the other direction, templates (for one example) often make it relatively easy to write code that is considerably faster than is practical in C. Just for one obvious example, C++ code using std::sort will often be two to three times as fast as equivalent C code using qsort.
Bottom line: the only reason for a C++ program to be slower than an equivalent written in C is if you've decided (for whatever reason) to write slower code. Common reasons are simplicity and readability -- and in most cases, those are more important than execution speed. Nonetheless, using C++ doesn't necessarily carry any speed penalty. It's completely up to you to decide whether to do something that might run more slowly.
C++ adheres to a "pay only for what you use" policy. You are not going to see performance hits due to the language choice; the performance of your application will be purely dependent upon your implementation.
Have you considered OCaml? Functional languages are well-suited for compiler writing. Pattern matching is an extremely useful construct, and the lack of side effects will make parallelization easy.
OCaml can be compiled to native code, and its performance is comparable to C and C++. Its standard library is somewhat lacking, but you don't really much else to write a compiler.
F# is a very similar language if you prefer a .NET environment.
People who write compilers in C as their basic language usually have the good sense to use tools for certain parts of it.
Specifically, go find out about lex and yacc (in their free implementations, flex and bison).
This advice almost certainly applies to any other language you choose, be it C++, Java or whatever.
I dont have any links but from what i hear and from experience C/C++ is a poor language to write a compiler with. First of all, do you really honestly need it to be scalable? Or scalable at this stage? Especially for a markup language? your not compiling 60+ mb of source so i dont think you actually need it to be scalable.
Anyways for my programming language i used bison for the parser (reading bison+flex is a must, try to avoid all conflicts my language has none). Then i use both C and C++ for the code. C because bison uses C and i just call a simple C function which creates and fill in a struct to create an abstract syntax tree. Then when its done it calls my C++ code that runs through the AST and generate the binary.
Standard ML is suppose to be really good with creating a language. If you dont use that a functional language is a good choice because it fits with the mindset (parsing may be left to right but your function calls wont be in that order). So i recommend that if you dont use bison (or know how to call it using C/C++ and bison).
Note: I tried writing a compiler twice. The first time in C without bison the 2nd time with bison. Theres no question that it would have taken me exponentially longer due to the fact that bison finds the conflicts for me and i am not doomed in debug land (i would probably in fact try to figure out a way to report conflicts before i write the code which is exactly what bison does)
Forget what programming language you use & also given that you have huge memory support in these modern computer era you could write good & fast programs using interpreted language and also very bad & slow running programs using C/C++ (compiled languages) & vice versa.
What is important is to use right data structures and algorithms & follow the style/patterns of the programming language you use to implement it. Remember that some one said "OO is not a panacea" & to the other extent some one else also said "show your data structures and I will code up the algorithm for the problem you are trying to solve".

Except OOP, why is C++ better than C? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Well that may sound like a troll question, but since C++ seems hard to fully master (and I never really knew STL was actually "part" of it), I wanted to know what are the disadvantages to use C instead of C++ when not relying much on OOP.
C++ can have a very much sophisticated syntax sometimes, which is kinda confusing me while trying to use OGRE3D for example...
Non-OO features that C++ has that C does not:
Templates
Function overloading
References
Namespaces
You can use structs and enums without writing struct or enum before every declaration or using typedefs.
Even if you don't define your own classes, using C++'s string and container classes is still often more convenient and safe to work with than c-style strings and arrays.
Type safety (even though some would call it weak)
Exceptions
Variable declarations in conditionals, C99 only has it in for
I'm a big fan of C who over time has become a big fan of C++. One of the big reasons for that is the STL ( the Standard Template Library ) and Boost.
Between the two of them it makes it very easy to write powerful portable applications.
Why C++ is better than C? Besides the obvious list of features, in my opinion the real answer is that there's no good reason to still use C instead of C++. Even if you don't use OOP, you can use it as a better C. Even if you use just once a unique feature of C++ in your program, C++ is already a winner.
On the other hand, there's no disadvantage in using C++: it retains the performance goals of C and it is a quite low level language, while allowing very powerful things. And you will not miss any C feature using C++!
And don't forget the wide user base and the rich libraries and frameworks available.
By the way, C99 has added some interesting features but after a decade there's still very limited compiler support (so you are bound to ANSI C). In the meantime C++ evolved as well and the compiler vendors are committed to providing conforming implementations.
One "feature" that hasn't been mentioned much (but I think is noteworthy) is that the C++ compiler community seems to be willing to go to a lot more work to produce conforming implementations. Back when the standard that eventually became C89/90 was in work, nearly every compiler vendor worked at conforming with the latest drafts of the standard, and (especially when the standard was close to complete) really put a lot of work into conforming as closely as they could.
That's no longer the case. The C99 standard was (obviously enough) completed over a decade ago, but there's still basically only one implementation that makes a serious attempt at conforming with the whole standard (Comeau). A few others (e.g., gcc) have added some C99 features, but are still missing a fair number of others. One (pcc) is in the rather paradoxical position of having added nearly all of the features specific to C99, but doesn't come very close to meeting the requirements of C89/90.
Given the complexity of C++, producing a conforming implementation is a much more difficult task. Despite this, I'd guess there are already more implementations that are at least really close to conforming with C++ 0x (due to be ratified a year or two from now) than with C99 (ratified roughly a decade ago). Just to pick an arbitrary number, I'd expect to see 3 conforming1 implementations of C++0x sooner than 3 conforming implementations of C99 (in fact, I'd almost expect that many the day it's ratified).
Of course, "conforming" in this case means "to a practical degree" -- I'm pretty sure every implementation of C and C++ has at least a few defects that prevents perfect conformance. The same is true for most other languages, the only obvious exceptions being languages that are defined in terms of a particular implementation.
References are done automatically and much safer compared to pointers, the standard library is far more extensive, templates make code extremely customizable and substantially faster and safer. C++ offers fantastic code use/reuse and organization. Also, if you don't rely much on OOP, then you're doing it wrong. There's times when objects are not appropriate, but they're not the majority of scenarios.
One reason to write libraries in C is that it is very easy to use that library across languages since the C ABI is very simple, compared to the name-mangling mess that is C++ ABI.
Creating C interfaces to the C++ libs might be a decent solution, but if you can express your API easily with C syntax, why write it in C++ to begin with?
Many C99 features are very nice, and are still not in C++.
[Note: this is a subjective response but the question itself tends to invoke subjective responses by nature].
C++ is a multi-paradigm language and there's a lot more to it than OOP. However, to suggest it's simply better than C is a bit... bold. :-D In the hands of an experienced C coder, and for the right purposes, C code can be very elegant and simple. Consider the Lua interpreter which is coded in C; it compiles to a very small binary which would have likely been a lot bigger even in the hands of an equally skilled C++ programmer, and is therefore well-suited for embedded use. C generally won't be as safe (ex: implicit casting, requires manual resource cleanup, etc) which is one thing which C++ strives to do a little better than C, but it also won't burden the programmer with awkward casting syntax (in C++ one shouldn't need to cast often, but in C it's quite common), e.g.
On the other hand, and I'm trying to speak very generally, C++ can actually make it easier to write more efficient code, particularly for code that needs to work across multiple types. The qsort vs std::sort benchmarks are a classic example of this and how C++, through templates and inlined function objects, can provide cost-free abstractions. In C one would have to write a separate sorting algorithm for every type by hand or stuff it in a macro to achieve comparable results.
Most C++ programmers who migrated from C never look back. I might be an oddball, but I still find C to be useful for implementing small scale libraries. For a start, it's a bit easier to port and builds super fast. For these kinds of things, I take implicit casting for granted. I would hate to work with any C code on a large scale, however, and have unfortunately have to do this from time to time.
As for specific differences, sepp2k already pointed out a pretty comprehensive list.
You can continue to write essentially C code but compile it as C++ and get the benefit of stronger type checking, and therefore more robust code.
You can then if you wish introduce the useful elements of C++ that have nothing to do with OO, such as a built-in bool, function overloading, and better defined const handling (no need to use macros for literal constant symbols).
It is not even too much of a stretch to using some of the easier to understand and use elements of the standard library such as std::string and iostreams, and even std::vector as a "better array"; you do not have to learn much C++ or understand OOP to take advantage of these improved interfaces.
Between OOP an procedural programming there is an intermediate Object Based Programming, which C++ supports and which is simpler to understand and learn and almost as useful as full OOP. Basically it uses abstract data types rather than full classes and eschews inheritance and polymorphism. To be honest it is what many C++ programmers write in any case.
Other than the upsides that sepp2k noted (and I aggree with) it certainly also has some little downsides that have not directly to do with OO. Come to mind the lack of __VA_ARGS__ for the preprocessor and the context sensitivity. Consider something like:
switch (argc) {
case 1: /* empty statement */;
toto T;
case 2: break;
}
In C, whenever the compiler encounters such a piece of code, and argc and toto are known, this is valid. (Sure we might get a warning for the unitialized T afterwards, whence we use it.)
In C++ this depends on the type toto. If it is a POD, everything is fine (well, as fine as for C). If it has a constructor the code is not valid: jump to case label crosses initialization of 'toto T'.
So in some sense, for C++ you must understand the underlying types to see if a control flow is valid.

Why are many VMs written in C when they look like they have C++ features?

I noticed some not so old VM languages like Lua, NekoVM, and Potion written in C.
It looked like they were reimplementing many C++ features.
Is there a benefit to writing them in C rather than C++?
I know something about Lua.
Lua is written in pure ANSI Standard C and compiles on any ANSI platform with no errors and no warnings. Thus Lua runs on almost any platform in the world, including things like Canon PowerShot cameras. It's a lot harder to get C++ to run on weird little embedded platforms.
Lua is a high-performance VM, and because C cannot express method calls (which might be virtual or might not) and operator overloading, it is much easier to predict the performance of C code just by looking at the code. C++, especially with the template library, makes it a little too easy to burn resources without being aware of it. (A full implementation of Lua including not only VM but libraries fits in 145K of x86 object code. The whole language fits even in a tiny 256K cache, which you find at L2 on Intel i7 and L1 on older chips. Unless you really know what you're doing, it's much harder to write C++ that compiles to something this small.)
These are two good reasons to write a VM in C.
It looked like they were reimplementing many C++ features.
Are you suggesting it's easier to implement polymorphism in C++ rather than C? I think you are greatly mistaken.
If you write a VM in C++, you wouldn't implement polymorphism in terms of C++'s polymorphism. You'd roll your own virtual table which maps function names to pointers, or something like that.
People are used to C. I have to admit that I'm more likely to write C for my own projects, even though I've been writing C++ since cfront 1.0.
If you want complete control over things, C is a little easier.
One obvious answer is interoperability. Any time language X has to call functions defined in language Y, you usually make sure that either X or Y is C (the language C, that is)
C++ doesn't define an ABI, so calling C++ code from another language is a bit tricky to do portably. But calling C code is almost trivial. That means that at least part of your VM is probably going to have to be written in C, and then why not be consistent and write the entire thing in C?
Another advantage of C is that it's simple. Everyone can read it, and there are plenty of programmers to help you write it. C++ is, for good and bad, much more of an experts language. You can do a lot of impressive things in C++, and it can save you a lot of work, but there are also fewer programmers who are really good at it.
It's much harder to be "good" at C++, and until one is good at it they will have a lot of bugs and problems. Now, especially when working on large projects with many people, the chance that one of them won't be good enough is much bigger, so coding the project in C is often less risky. There are also portability issues - C code is much easier to port across compilers than C++.
Lua also has many features that are very easy to implement in Lisp, so why doesn't it take that as a basis? The point is that C is little more than glorified assembler code with only a thin layer of abstraction. It is like a somewhat polished blank slate, on which you can build your higher level abstractions. C++ is such a building. Lua is a different building, and if it had to use C++ abstractions, it would have to bend its intent around the existing C++ structure. Starting from the blank slate instead gives you the freedom to build it like you want.
In many cases, code in C could be much faster than C++. For instance most of the functions in the stdio.c library are faster than iostream. scanf is faster than cin, printf is faster than cout etc.
and VMs demand high performance, so C code makes perfect sense, although the programs would most probably take longer to develop.
C++ is implemented in C. I suspect everyone was following the C++ approach.
Even though modern C++ compilers skip (or conceal) the explicit C++ to C translation as a discrete step, the C++ language has peculiarities that stem from the underlying C implementation.
Two examples.
Pointers in addition to references is entirely because of C. References are sufficient, and that's the way Java, Python and Ruby all work.
The classes are not first-class objects that exist at run-time because the class is only a way to define the attributes and method functions in the underlying C code. Class objects exist at run-time in Java, Python and Ruby, and can be manipulated.
Just a side note, you should look into CLR (Rotor-incarnation) and Java sources and you will note it is far more C++-as-C rather than modern or good C++. So it has a parallel there and it is a side-effect of abstracting for toys and making it average-performance happy for the crowd in managed languages.
It also helps avoid pitfalls of naive C++ usage. Exceptions and all other sort of things (bits David at boost consulting kicked off and more while we build sequencers and audio sampling before he even had a job :) are an issue too..
Python integration is another matter, and has a messy history in boost for example.. But for primitive data types and interfaces/interop and machine abstraction, well it is quite clear nothing beats C. No compiler issues either, and it still bootstraps many things before you get to anything as influential as it is/was/will be.
Stepanov recognised this achievement when he nailed STL, and Bjarne nailed it with templates.. Those are the three things always worth thinking about, as you don't have a decent incarnation of them in popular managed languages, not to that expressivness and power. All of that more than 20 years later, which is remarkable and all still bootstrap via C/C++.. Legacy of goodness (but I'm not defending 'dark age' C code c1982-2000, just the idea, yuo can misuse anything ).

Why would anybody use C over C++? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Although people seem to like to complain about C++, I haven't been able to find much evidence as to why you would want to choose C over C++. C doesn't seem to get nearly as much flak and if C++ has all these problems why can't you just restrict yourself to the C subset? What are your thoughts/experience?
Joel's answer is good for reasons you might have to use C, though there are a few others:
You must meet industry guidelines, which are easier to prove and test for in C
You have tools to work with C, but not C++ (think not just about the compiler, but all the support tools, coverage, analysis, etc)
Your target developers are C gurus
You're writing drivers, kernels, or other low-level code
You know the C++ compiler isn't good at optimizing the kind of code you need to write
Your app not only doesn't lend itself to be object-oriented but would be harder to write in that form
In some cases, though, you might want to use C rather than C++:
You want the performance of assembler without the trouble of coding in assembler (C++ is, in theory, capable of 'perfect' performance, but the compilers aren't as good at seeing optimizations a good C programmer will see)
The software you're writing is trivial, or nearly so - whip out the tiny C compiler, write a few lines of code, compile and you're all set - no need to open a huge editor with helpers, no need to write practically empty and useless classes, deal with namespaces, etc. You can do nearly the same thing with a C++ compiler and simply use the C subset, but the C++ compiler is slower, even for tiny programs.
You need extreme performance or small code size and know the C++ compiler will actually make it harder to accomplish due to the size and performance of the libraries.
You contend that you could just use the C subset and compile with a C++ compiler, but you'll find that if you do that you'll get slightly different results depending on the compiler.
Regardless, if you're doing that, you're using C. Is your question really "Why don't C programmers use C++ compilers?" If it is, then you either don't understand the language differences, or you don't understand the compiler theory.
I like minimalism & simplicity.
Because they already know C
Because they're building an embedded app for a platform that only has a C compiler
Because they're maintaining legacy software written in C
You're writing something on the level of an operating system, a relational database engine, or a retail 3D video game engine.
Fears of performance or bloat are not good reason to forgo C++. Every language has its potential pitfalls and trade offs - good programmers learn about these and where necessary develop coping strategies, poor programmers will fall foul and blame the language.
Interpreted Python is in many ways considered to be a "slow" language, but for non-trivial tasks a skilled Python programmer can easily produce code that executes faster than that of an inexperienced C developer.
In my industry, video games, we write high performance code in C++ by avoiding things such as RTTI, exceptions, or virtual-functions in inner loops. These can be extremely useful but have performance or bloat problems that it's desirable to avoid. If we were to go a step further and switch entirely to C we would gain little and lose the most useful constructs of C++.
The biggest practical reason for preferring C is that support is more widespread than C++. There are many platforms, particularly embedded ones, that do not even have C++ compilers.
There is also the matter of compatibility for vendors. While C has a stable and well-defined ABI (Application Binary Interface) C++ does not. The ABI in C++ is more complicated due to such things as vtables and constructurs/destructors so is implemented differently with every vendor, and even versions of a vendors toolchain.
In real-terms this means you cannot take a library generated by one compiler and link it with code or a library from another which creates a nightmare for distributed projects or middleware providers of binary libraries.
I take the other view: why use C++ instead of C?
The book The C Programming Language (aka: K&R) tells you clearly how to do everything the language can do in under 300 pages. It's a masterpiece of minimalism. No C++ book even comes close.
The obvious counterargument is that the same could be said of most, if not all, modern languages -- they also can't tell you how to do everything in only a few hundred pages. True. So why use C++ instead? Feature richness? Power? If you need something more feature rich or powerful then go with C#, Objective C, Java, or something else like that. Why burden yourself with the complexities of C++? If you need the degree of control C++ grants then I argue to use C. C can do anything and can do it well.
I choose to write in C because I enjoy working with a small, tight language. I like having access to a standard which can be read in a reasonable amount of time (for me -- I'm a very slow reader). Moreover, I use it to write software for embedded systems for which few desirable C++ compilers exist (like some PIC micro-controllers).
In addition to several other points mentioned already:
Less surprise
that is, it is much easier to see what a piece of code will do do exactly . In C++ you need to approach guru level to be able to know exactly what code the compiler generates (try a combination of templates, multiple inheritance, auto generated constructors, virtual functions and mix in a bit of namespace magic and argument dependent lookup).
In many cases this magic is nice, but for example in real-time systems it can really screw up your day.
I'm used to use C++ for my projects. Then I got a job where plain C is used (a 20 year old evolving codebase of an AV software with poor documentation...).
The 3 things I like in C are:
Nothing is implicit: you see what your program exactly does or not does. This makes debugging easier.
The lack of namespaces and overloads can be an advantage: if you want to know where a certain function is called, just grep through the source code directory and it will tell you. No other special tools needed.
I rediscovered the power of the function pointers. Basically they allow you to do all polymorphic stuff you do in C++, but they are even more flexible.
Linus' answer to your question is "Because C++ is a horrible language"
His evidence is anecdotal at best, but he has a point..
Being more of a low level language, you would prefer it to C++..C++ is C with added libraries and compiler support for extra features (both languages have features the other language doesn't, and implement things differently), but if you have the time and experience with C, you can benefit from extra added low level related powers...[Edited](because you get used to doing more work manually rather than benefit from some powers coming from the language/compiler itself)
Adding links:
Why C++ for embedded
Why are you still using C? PDF
I would google for this.. because there are plenty of commentaries on the web already
Because they're writing a plugin and C++ has no standard ABI.
Long compile times can be annoying. With C++ you can have very long compile times (which means, of course, more time for Stack Overflow!).
If you want your code to be understood by virtually any programmer write in C.
I'm surprised no one's mentioned libraries. Lots of languages can link against C libs and call C functions (including C++ with extern "C"). C++ is pretty much the only thing that can use a C++ lib (defined as 'a lib that uses features in C++ that are not in C [such as overloaded functions, virtual methods, overloaded operators, ...], and does not export everything through C compatible interfaces via extern "C"').
Because they want to use features in C99 that don't have equivalents in C++.
However, there aren't as many C99 features that are useful to C++ as people think at first glance. Variable-length arrays? C++ has std::vectors. Support for complex/imaginary numbers? C++ has a templated complex type. Type-generic math functions? C++ overloaded the standard math functions, causing the same result.
Named initializers? Not in C++, but there's a workaround:
struct My_class_params {
int i;
long j;
std::string name;
My_class_params& set_i(int ii)
{
i = ii;
return *this;
}
My_class_params& set_j(long jj)
{
j = jj;
return *this;
}
template <typename STRING>
My_class_params& set_name(STRING&& n)
{
name = std::forward<STRING>(n);
return *this;
}
My_class_params()
{
// set defaults
}
};
class My_class {
My_class_params params;
public:
My_class(const My_class_params& p) : params(p) { }
...
};
This allows you to write things like:
My_class mc(My_class_params().set_i(5).set_name("Me"));
This is pretty shallow but as a busy student I chose C because I thought C++ would take too long to learn. Many professors at my university won't accept assignments in Python and I needed to pick up something quickly.
Because for many programming tasks C is simpler, and good enough. When I'm programming lightweight utilities especially, I can feel like C++ wants me to build in an elegant supersructure for its own sake, rather than simply write the code.
OTOH, for more complex projects, the elegance provides more good solid structural rigor than would naturally flow out of my keyboard.
Most of the significant features of c++ somehow involve classes or templates. These are wonderful features except for the way the compiler transforms these into object code. Most compilers use name mangling, and the ones that don't do something at least as messy.
If your system lives on its own, as is the case with many applications, then C++ is a fine choice.
If your system needs to interact with software not neccesarily written in C++ (most frequently in assembler, or Fortran Libraries) then you are in a tight spot. To interact with those kinds of cases, you'll need to disable name mangling for those symbols. this is usually done by declaring those objects extern "C", but then they can't be templates, overloaded functions, or classes. If those are likely to be your applications API, then you'll have to wrap them with helper functions, and keep those functions in sync with the actual implementations.
And in reality, the C++ language provides a standard syntax for features that can be easily implemented in pure C.
In short, the overhead of interoperable C++ is too high for most folks to justify.
Oh my, C vs C++, a great way to start a flame war. :)
I think C is better for driver and embedded code.
C++ has some great features that C doesn't have, but many of the object oriented features of C++ can cause monumental coding messes when people write code with non-obvious side-effects that occur behinds the scenes. Crazy code can be hidden in constructors, destructors, virtual functions, ... The beauty of C code is the language does nothing non-obvious behind your back, thus you can read the code and not have to look up at every constructor and destructor and so on. A lot of the problem is bad coding practices by SOME people.
My perfect language would be a combination of C99 plus a minimal subset of safer C++ capabilities that adds ZERO (or near zero) compiler overhead to the binary output. Perfect additions would be class encapsulation and naming concepts of data and functions.
One remark about "just use the subset of C++ you want to use": the problem with this idea is that it has a cost to enforce that everybody in the project uses the same subset. My own opinion is that those costs are quite high for loosely coupled projects (e.g. open source ones), and also that C++ totally failed at being a better C, in the sense that you cannot use C++ wherever you used C.
I haven't been able to find much evidence as to why you would want to choose C over C++.
You can hardly call what I'm about to say evidence; it's just my opinion.
People like C because it fits nicely inside the mind of the prgrammer.
There are many complex rules of C++ [when do you need virtual destructors, when can you call virtual methods in a constructor, how does overloading and overriding interact, ...], and to master them all takes a lot of effort. Also, between references, operator overloading and function overloading, understanding a piece of code can require you to understand other code that may or may not be easy to find.
A different question in why organizations would prefer C over C++. I don't know that, I'm just a people ;-)
In the defense of C++, it does bring valuable features to the table; the one I value most is probably parametric('ish) polymorphism, though: operations and types that takes one or more types as arguments.
I would say that C gives you better control over optimization and efficiency than C++ and hence would be useful in situations where memory and other resources are limited and every optimization helps. It also has a smaller footprint of course.
There's also the approach some shops take of using some of C++'s features in a C-like way, but avoiding ones that are objectionable. For example, using classes and class methods and function overloading (which are usually easy for even C diehards to cope with), but not the STL, stream operators, and Boost (which are harder to learn and can have bad memory characteristics).
Because you're writing for a system where resources are tight (such as an embedded system, or some kind real bare metal code like a kernel) and you want as little overhead as possible.
There's a reason why most embedded systems don't have a C++ compiler - it's not that people don't want one, it's that cramming C++ code into that small a space is task that approaches impossible.
Until some years ago the existing C++ compilers were missing important features, or the support was poor and the supported features vary wildly among them, and so it was hard to write portable applications.
Because of the no standard naming of symbols it is difficult for other languages/applications to support C++ classes directly.
What C needed was a better preprocessor.
cfront was one and thus born c++
I'ld use C, where the 'c++ as preprocessor' would not be okay.
I'm pretty sure, at the bottom of any well written c++ library/framework/toolkit,
you would find dirty-old-c ( or static casts, which is same )