Should "portable" C compile as C++? - c++

I got a comment to an answer I posted on a C question, where the commenter suggested the code should be written to compile with a C++ compiler, since the original question mentioned the code should be "portable".
Is this a common interpretation of "portable C"? As I said in a further comment to that answer, it's totally surprising to me, I consider portability to mean something completely different, and see very little benefit in writing C code that is also legal C++.

The current C++ (1998) standard incorporates the C (1989) standard. Some fine print regarding type safety put aside, that means "good" C89 should compile fine in a C++ compiler.
The problem is that the current C standard is that of 1999 (C99) - which is not yet officially part of the C++ standard (AFAIK)(*). That means that many of the "nicer" features of C99 (long long int, stdint.h, ...), while supported by many C++ compilers, are not strictly compliant.
"Portable" C means something else entirely, and has little to do with official ISO/ANSI standards. It means that your code does not make assumptions on the host environment. (The size of int, endianess, non-standard functions or errno numbers, stuff like that.)
From a coding style guide I once wrote for a cross-platform project:
Cross-Platform DNA (Do Not Assume)
There are no native datatypes. The only datatypes you might use are those declared in the standard library.
char, short, int and long are of different size each, just like float, double, and long double.
int is not 32 bits.
char is neither signed nor unsigned.
char cannot hold a number, only characters.
Casting a short type into a longer one (int -> long) breaks alignment rules of the CPU.
int and int* are of different size.
int* and long* are of different size (as are pointers to any other datatype).
You do remember the native datatypes do not even exist?
'a' - 'A' does not yield the same result as 'z' - 'Z'.
'Z' - 'A' does not yield the same result as 'z' - 'a', and is not equal to 25.
You cannot do anything with a NULL pointer except test its value; dereferencing it will crash the system.
Arithmetics involving both signed and unsigned types do not work.
Alignment rules for datatypes change randomly.
Internal layout of datatypes changes randomly.
Specific behaviour of over- and underflows changes randomly.
Function-call ABIs change randomly.
Operands are evaluated in random order.
Only the compiler can work around this randomness. The randomness will change with the next release of the CPU / OS / compiler.
For pointers, == and != only work for pointers to the exact same datatype.
<, > work only for pointers into the same array. They work only for char's explicitly declared unsigned.
You still remember the native datatypes do not exist?
size_t (the type of the return value of sizeof) can not be cast into any other datatype.
ptrdiff_t (the type of the return value of substracting one pointer from the other) can not be cast into any other datatype.
wchar_t (the type of a "wide" character, the exact nature of which is implementation-defined) can not be cast into any other datatype.
Any ..._t datatype cannot be cast into any other datatype
(*): This was true at the time of writing. Things have changed a bit with C++11, but the gist of my answer holds true.

No. My response Why artificially limit your code to C? has some examples of standards-compliant C99 not compiling as C++; earlier C had fewer differences, but C++ has stronger typing and different treatment of the (void) function argument list.
As to whether there is benefit to making C 'portable' to C++ - the particular project which was referenced in that answer was a virtual machine for a traits based language, so doesn't fit the C++ object model, and has a lot of cases where you are pulling void* of the interpreter's stack and then converting to structs representing the layout of built-in object types. To make the code 'portable' to C++ it would have add a lot of casts, which do nothing for type safety.

Portability means writing your code so that it compiles and has the same behaviour using different compilers and/or different platforms (i.e. relying on behaviour mandated by the ISO standard(s) wherever possible).
Getting it to compile using a different language's compiler is a nice-to-have (perhaps) but I don't think that's what is meant by portability. Since C++ and C are now diverging more and more, this will be harder to achieve.
On the other hand, when writing C code I would still avoid using "class" as an identifier for example.

No, "portable" doesn't mean "compiles on a C++ compiler", it means "compiles on any Standard comformant C compiler" with consistent, defined behavior.
And don't deprive yourself of, say, C99 improvements just to maintain C++ compatibility.
But as long as maintaining compatibility doesn't tie your hands, if you can avoid using "class" and "virtual" and the the like, all the better. If you're writing open source, someone may want to port your code to C++; if you're wring for hire, you company/client may want to port sometime in the future. hey, maybe you'll even want to port it to C++ in the future
Being a "good steward" not leaving rubbish around the campfire, is just good karma in whatever you do.
And please, do try to keep incompatibilities out of your headers. Even if your code is never ported, people may need to link to it from C++, so having a header that doesn't use any C++ reserved words, is cool.

It depends. If you're doing something that might be useful to a C++ user, then it might be a good idea. If you're doing something that C++ users would never need but that C users might find convenient, don't bother making it C++ compliant.
If you're writing a program that does something a lot of people do, you might consider making it as widely-usable as possible. If you're writing an addition to the Linux kernel, you can throw C++ compatability out the window - it'll never be needed.
Try to guess who might use your code, and if you think a lot of C++ fans might find your code useful, consider making it C++ friendly. However, if you don't think most C++ programmers would need it (i.e. it's a feature that is already fairly standardized in C++), don't bother.

It is definitely common practice to compile C code using a C++ compiler in order to do stricter type checking. Though there are C-specific tools to do that like lint, it is more convenient to use a C++ compiler.
Using a C++ compiler to compile C code means that you commonly have to surround your includes with extern "C" blocks to tell the compiler not to mangle function names. However this is not legal C syntax. Effectively you are using C++ syntax and your code which is supposedly C, is actually C++. Also a tendency to use "C++ convenience" starts to creep in like using unnamed unions.
If you need to keep your code strictly C, you need to be careful.

FWIW, once a project gains a certain size and momentum, it is not unlikely that it may actually benefit from C++ compatibility: even if it not going to be ported to C++ directly, there are really many modern tools related to working/processing C++ source code.
In this sense, a lack of compatibility with C++, may actually mean that you may have to come up with your own tools to do specific things. I fully understand the reasoning behind favoring C over C++ for some platforms, environments and projects, but still C++ compatibility generally simplifies project design in the long run, and most importantly: it provides options.
Besides, there are many C projects that eventually become so large that they may actually benefit from C++'s capabilities like for example improved suport for abstraction and encapsulation using classes with access modifiers.
Look at the linux (kernel) or gcc projects for example, both of which are basically "C only", still there are regularly discussions in both developer communities about the potential gains of switching to C++.
And in fact, there's currently an ongoing gcc effort (in the FSF tree!) to port the gcc sources into valid C++ syntax (see: gcc-in-cxx for details), so that a C++ compiler can be used to compile the source code.
This was basically initiated by a long term gcc hacker: Ian Lance Taylor.
Initially, this is only meant to provide for better error checking, as well as improved compatibility (i.e. once this step is completed, it means that you don't necessarily have to have a C compiler to to compile gcc, you could also just use a C++ compiler, if you happen to be 'just' a C++ developer, and that's what you got anyway).
But eventually, this branch is meant to encourage migration towards C++ as the implementation language of gcc, which is a really revolutionary step - a paradigm shift which is being critically perceived by those FSF folks.
On the other hand, it's obvious how severely gcc is already limited by its internal structure, and that anything that at least helps improve this situation, should be applauded: getting started contributing to the gcc project is unnecessarily complicated and tedious, mostly due to the complex internal structure, that's already to started to emulate many of the more high level features in C++ using macros and gcc specific extensions.
Preparing the gcc code base for an eventual switch to C++ is the most logical thing to do (no matter when it's actually done, though!), and it is actually required in order to remain competitive, interesting and plain simply relevant, this applies in particular due to very promising efforts such as llvm, which do not bring all this cruft, complexity with them.
While writing very complex software in C is often course possible, it is made unnecessarily complicated to do so, many projects have plain simply outgrown C a long time ago. This doesn't mean that C isn't relevant anymore, quite the opposite. But given a certain code base and complexity, C simply isn't necessarily the ideal tool for the job.
In fact, you could even argue that C++ isn't necessarily the ideal language for certain projects, but as long as a language natively supports encapsulation and provides means to enforce these abstractions, people can work around these limitations.
Only because it is obviously possible to write very complex software in very low level languages, doesn't mean that we should necessarily do so, or that it really is effective in the first place.
I am talking here about complex software with hundreds of thousands lines of code, with a lifespan of several decades. In such a scenario, options are increasingly important.

No, matter of taste.
I hate to cast void pointers, clutters the code for not much benefit.
char * p = (char *)malloc(100);
vs
char * p = malloc(100);
and when I write an "object oriented" C library module, I really like using the 'this' as my object pointer and as it is a C++ keyword it would not compile in C++ (it's intentional as these kind of modules are pointless in C++ given that they do exist as such in stl and libraries).

Why do you see little benefit? It's pretty easy to do and who knows how you will want to use the code in future.

No, being compilable by C++ is not a common interpretation of portable. Dealing with really old code, K&R style declarations are highly portable but can't be compiled under C++.
As already pointed out, you may wish to use C99 enhancements. However, I'd suggest you consider all your target users and ensure they can make use of the enhancements. Don't just use variable length arrays etc. because you have the freedom to but only if really justified.
Yes it is a good thing to maintain C++ compatibility as much as possible - other people may have a good reason for needing to compile C code as C++. For instance, if they want to include it in an MFC application they would have to build plain C in a separate DLL or library rather than just being able to include your code in a single project.
There's also the argument that running a compiler in C++ mode may pick up subtle bugs, depending on the compiler, if it applies different optimisations.

AFAIK all of the code in classic text The C programming language, Second edition can be compiled using a standard C++ compilers like GCC (g++). If your C code is upto the standards followed in that classic text, then good enough & you're ready to compile your C code using a C++ compiler.
Take the instance of linux kernel source code which is mostly written in C with some inline assembler code, it's a nightmare compiling the linux kernel code with a C++ compiler, because of least possible reason that 'new' is being used as an variable name in linux kernel code, where as C++ doesn't allow the usage of 'new' as a variable name. I am just giving one example here. Remember that linux kernel is portable & compiles & runs very well in intel, ppc, sparc etc architectures. This is just to illustrate that portability does have different meanings in software world. If you want to compile C code using a C++ compiler, you are migrating your code base from C to C++. I see it as two different programming languages for most obvious reason that C programmers doesn't like C++ much. But I like both of them & I use both of them a lot. Your C code is portable, but you should make sure you follow standard techniques to have your C++ code portable while you migrate your C code to C++ code. Read on to see from where you'd get the standard techniques.
You have to be very careful porting the C code to C++ code & the next question that I'd ask is, why would you bother to do that if some piece of C code is portable & running well without any issues? I can't accept managebility, again linux kernel a big code source in C is being managed very well.
Always see the two programming languages C & C++ as different programming languages, though C++ does support C & its basic notion is to always support for that wonderful language for backward compatibility. If you're not looking at these two languages as different tools, then you fall under the land of popular, ugly C/C++ programming language wars & make yourself dirty.
Use the following rules when choosing portability:
a) Does your code (C or C++) need to be compiled on different architectures possibly using native C/C++ compilers?
b) Do a study of C/C++ compilers on the different architectures that you wish to run your program & plan for code porting. Invest good time on this.
c) As far as possible try to provide a clean layer of separation between C code & C++ code. If your C code is portable, you just need to write C++ wrappers around that portable C code again using portable C++ coding techniques.
Turn to some good C++ books on how to write portable C++ code. I personally recommend The C++ programming language by Bjarne Stroustrup himself, Effective C++ series from Scott meyers & popular DDJ articles out there in www.ddj.com.
PS: Linux kernel example in my post is just to illustrate that portability does mean different meanings in software programming & doesn't criticize that linux kernel is written in C & not in C++.

Related

correct me if my understanding of c++ is wrong

correct me if any of my following current understanding of c++ is wrong:
C++ is an extended version of C. Therefore, C++ is just as efficient as C.
Moreover, any application written in C can be compiled using C++ compilers
C syntax is also valid C++ syntax
C++ is at the exact same language level hierarchy as C.
Language Level Hierarchy
eg. lowest-level: assembly language,
high-levels: Java, PHP, etc
so my interpretation is that
C++/C is at a lower level than Java,PHP etc since it's closer to hardware level (and therefore because of this,it's more efficient than Java, PHP, etc), yet it is not as extreme as assembly language....but C++/C is at the same level with each other and neither one is closer to hardware level
If you start with code that's legal as both C and C++, it will typically compile to the same result with both, or close enough that efficiency is only minimally affected.
It's possible to write C that isn't allowable as C++ (e.g., using a variable with a name that's the same as one of the key words added in C++, such as new). Most such cases, however, are trivial to convert so they're allowed in C++. Probably the most difficult case to convert is code that uses function declarations instead of prototypes (or uses functions without declarations at all, which was allowed in older versions of C).
See 2 -- some syntactical C won't work as C++. As noted, it's usually trivial to convert though.
No, not really. Although C++ does provide the same low-level operations as C, it also has higher-level operations that C lacks.
C++ is at the exact same language level hierarchy as C.
Language Level Hierarchy
eg. lowest-level: assembly language, high-levels: Java, PHP, etc
Programming languages are often categorised from 1st generation (machine code), 2nd generation (assembly language), 3rd generation (imperative languages), 4th generation (definition's a bit vague - domain-specific languages intended for high productivity, e.g. SQL), 5th generation (typical language of the problem expression, e.g. maths notation, logic, or a human language; Miranda, Prolog). See e.g. http://en.wikipedia.org/wiki/Fifth-generation_programming_language and its links.
In that sense, C and C++ are both 3rd generation languages. (As Jerry points out, so are PHP, Java, PERL, Ruby, C#...). Using that yardstick, these languages belong in the same general group... they're all languages in which you have to tell the computer how to solve the problem, but not at a CPU-specific level.
In another sense though, C++ has higher level programming concepts than C, such as Object Orientation, functors, and more polymorphic features including templates and overloading, even though they're all ways to organise and access the steps for solving the problem. Higher level languages (i.e. 5GL) don't need to be told that - rather, they just need a description of the problem and knowing how to solve the entire domain of problems they find a workable approach for your specific case.
C++/C is at a lower level than Java,PHP etc since it's closer to hardware level (and therefore because of this,it's more efficient than Java, PHP, etc), yet it is not as extreme as assembly language....but C++/C is at the same level with each other and neither one is closer to hardware level
This is confusing things a bit. Summarily:
C++ and C do span lower than Java/PHP, yes.
C++ and C do tend to be more efficient, yes. You can get a general impression of this at http://benchmarksgame.alioth.debian.org/u64q/which-programs-are-fastest.html - don't take it too literally, it depends a lot on your problem space.
C++ and C both go as low as each other, but C++ has some higher level programming support too (though it's still a 3GL like C).
Let's look at a few examples:
bit shifting: Java is designed to be more portable (sometimes at the expense of performance) than C or C++, so even with JIT certain operations might be a bit inefficient on some platforms, but it may be convenient that they operate predictably. If you're doing equivalent work, and care about the edge cases where CPU behaviours differ, you'll find C and C++ leave operator behaviour for the implementation to specify. You may need to write multiple versions of the code for the different deployment platforms, only to end up getting pretty much the same performance as Java (but programs often know they won't exercise edge cases, or don't care about the behavioural differences). In that respect, Java has abstracted away a low-level concern and could reasonably be considered higher level but pessimistic.
C++ provides some higher level facilities such as templates (and hence template metaprogramming), and multiple inheritance. Compilers commonly provide low level facilities such as inline assembly and the ability to call arbitrary functions from other objects/libraries as long as the function signatures are known at compile time (some libraries work around this limitation). Interpreted (e.g. PHP) and Virtual Machine based (e.g. Java) languages tend to be worse at this.
Java also provides some higher level facilities that C++ lacks - e.g. introspection, serialisation.
Generally, I tend to conceive of C++ spanning both lower and higher than Java. Put another way, Java overlaps a section in the middle of C++'s span. But, Java has a few stand-out high-level features too.
PHP is an interpreted language that again abstracts away some low level concerns, but generally fails to provide good facilities for more abstract or robust programming techniques too. Like most interpreters, it does allow run-time evaluation of arbitrary source code, as well as run-time modification of class metadata etc., which allows a high level, powerful but dangerously unstructured approach to programming. That kind of thing isn't possible in a compiled language unless the compiler is shipped in the deployment environment (and even then there are more limitations).
C++ is an extended version of C. Therefore, C++ is just as efficient as C.
Generally true.
Moreover, any application written in C can be compiled using C++ compilers
C syntax is also valid C++ syntax
There are some trivial differences, e.g.:
in C++, main() must have return type int and implicitly returns 0 on exit if not return statement's encountered, but C allows void or int and for the latter must explicitly return an int
C++ has additional keywords (e.g. mutable, virtual, class, explicit...) that are therefore not legal C++ identifiers, but are legal in C
Still, your conception is essentially true.
1/4 and 2/3 seem to be saying very similar things, but:
Yes (Depends on what you mean by "extended", but at a broad level, yes)
Not always
Not always
Yes
Moreover, any application written in C
can be compiled using C++ compilers
Not every C program can be compiled using a C++ compiler. There are some differences between C and C++ (keywords, for example), that prevent mixing C and C++ in some ways. Stroustrup adresses some important points in C and C++: Siblings.
C++ is an extended version of C.
Therefore, C++ is just as efficient as
C.
That depends on the language features you use. I heard that using OOP might bring more cache misses than using a more C-like approach. I can't tell wether this is true or not, as I didn't read more on that subject. But it might be something which should be considered. This is only one example were performance isn't easy comparable.
This isn't exactly true, beyond extra C++ language features that are slower, there are different optimizations that can be done that will change this. Due to the better C++ type system, these are actually normally in C++'s favor however.
No, a big case is that C++ doesn't support automatic cast from void* so for instance
char* c = malloc(10); // Is valid C, but not C++
char* c = (char*)malloc(10) //Is required in C++
Except for C99 and newer C features, I think this is nearly always the case. Keep in mind this is only taking into account syntax this doesn't mean that everything that can compile in C can also compile in C++.
Could you elaborate on what you mean by this, what do you mean by "language level hierarchy"?
Summary:
True.
Dangerously false.
False.
Subjective
Some examples for 2/3:
sizeof 'a' is 1 in C++ and sizeof(int) in C.
char *s = malloc(len+1); is correct C but invalid C++.
char s[2*strlen(name)+1]; is valid (albeit dangerous) C, but invalid C++.
sizeof (1?"hello":"goodbye") issizeof(char *)` in C but 6 in C++.
Attempting to compile existing C code as C++ is simply invalid and likely to produce dangerous bugs even if you hunt down and "fix" all the compile-time errors. And writing code that's valid in both languages is perhaps a reasonable entry for a polyglot competition, but not for any serious use. The intersection of C and C++ is actually a very ugly language that's the worst of both worlds.
Your understanding is wrong in some of your points:
1) your first point is right.C++ is an extension of c.
2) second point is right . C can be compiled using c++ compilers.
3) Some of C syntax varies from c++. In c++, using structure , c should specify structure name but c++ it is not mandatory to specify structure name.Also C++ have the concept of class that is not available in c. C++ also have higher security mechanisms.
4)C is procedural language but c++ is object oriented approach. so c++ is not at the exact same language level hierarchy as c.
C language is not a subset of C++ lanaguage. Check the C99 spec for example - it will not compile in C++ compiler easily. However most of C89 source code can be copied&paste to C++ source code.
C and C++ are languages that can be implemented with "zero overhead" comparing to bare iron.
No. But most of C++ compilers are C compilers too. It means that you can compile .C and .C++ files using the same toolchain.
No, The evolution of these languages differs. See answer to question 1.
C++ is multiparadigm language. Yes, it can be used in the same way as C. But it can be used as DSL too - it provides greater abstraction level.
That's a whole big question to answer.
Not in all cases!
not true because of 3
not true
They are not exactly the same
I don't think language level hierarchy matters too much for a thing. For example, C is a high-level one compared to assembly language while it's a low-level one compared with Java/C#.

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.

Learning C when you already know 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.

Why are most of the biggest open source projects in C? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm having a debate with a friend and we're wondering why so many open source projects have decided to go with C instead of C++. Projects such as Apache, GTK, Gnome and more opted for C, but why not C++ since it's almost the same?
We're precisely looking for the reasons that would have led those projects (not only those I've listed but all C projects) to go with C instead of C++. Topics can be performance, ease of programming, debugging, testing, conception, etc.
C is very portable, much more than C++ was 10 years ago.
Also, C is very entrenched in the Unix tradition. Read more in 'The Art of Unix Programming', about Unix and OO in general, and about specific languages on unix (including C and C++).
There are numerous counter examples: everything based on Qt for one.
Also, on my Debian testing system:
edd#ron:~$ apt-cache rdepends libstdc++6|wc -l
4101
So that's 4101 packages depending on the basic C++ library. For comparison, I get about 14,982 for libc6 or roughly 3.6 as many. But it is not if there aren't any C++ projects in Open Source land.
Edit: Thinko on my part: as the C++ packages also depend on libc6, the ratio really is
(14982 - 4101)/4101 = 2.65
so there are roughly 2 1/2 times as many packages implemented in C than there are in C++.
Eric Raymond's wonderful book "The Art of Unix Programming" has some reflections on this issue (the whole book is well worth reading in either the paper or free online editions, I'm just pointing to the relevant section -- Eric was involved with the coining and introduction of the term "open source", and is always well worth reading;-0).
Summarizing that section, Raymond claims that "OO languages show some tendency to suck programmers into the trap of excessive layering" and Unix programmers (and by extension open-source programmers) resist that trap of "thick glue".
Later in the book, you find some considerations specifically about C++, such as "It may be that C++'s realization of OO is particularly problem-prone". Whether you agree or not, the whole text is well worth reading (I can hardly do it justice here!-), and rich with bibliography pointing you to many other relevant studies and publications.
Linus Torvalds has ranted several times on the topic of C++ -- he uses C for git, and of course the Linux kernel is mostly C:
on C++ and git (warning: don flame-retardant first)
an interview with Linus from 1998
You can easily find more of these, and while it's in his nature to get a bit flamey about these things, there are some valid points.
One of the more interesting (from where I'm sitting, anyway) is the observation that C++ compilers and libraries were (and to some degree are) a lot more buggy than the corresponding C compilers. This stands to reason given the relative complexities of the two languages.
It smells a little of "not invented here" (NIH) syndrome, but when you have the entire Linux kernel developer base, you can sometimes afford to reinvent things "The Right Way".
A lot of the projects started before C++ was standardized, so C was the obvious choice and a change later would be hard. C was standardized about a decade before C++, and has been more nearly portable for even longer. So, it was largely a pragmatic decision at the time, inspired in part by the Unix heritage of using C for most code.
C++ is a mess. It is overly complicated language, so complicated that only few people can say that they know all the bits. And fewer compilers which really complies to C++ standard.
So I think the reason is simplicity and portability.
If you want higher-level and object-oriented programming, then I think C++ is just competed with others like Python. (Note that I programmed in C++ few years, it's fast and has some features from higher-level languages that speeds up development, no offence.)
I have worked on a few C++ projects in my time, all of which have ended in tears one way or the other. At the most fundamental level, the truth is that people can't be trusted. They can't be trusted to write good code, they can't be trusted to debug it, and they certainly can't be trusted to understand it when they have to come back and modify it again weeks/months later.
C code doesn't have a lot of the weird stuff in C++ that makes it hard to debug (constructors/destructors, anything that happens with static global objects during cpp_initialize() time, etc.). That just makes it easier to deal with when developing and maintaining a big project.
Maybe I'm a luddite, but every time someone says "C++" around me I get shivers.
Some people have mentioned portability, but in this day, the portability of C++ isn't much of an issue (it runs on anything GCC runs on, which is essentially anything). However, portability is more than just architecture-to-architecture or OS-to-OS. In the case of C++, it includes compiler-to-compiler.
Let's discuss ABI, or Application Binary Interface. This basically means "how your code translates into assembly." In C, when you write:
int dostuff(const char *src, char *dest);
You know that you're making a symbol in your object file called _dostuff (C global names are all prefixed by an underscore in the resultant assembly). But in C++, when you write this:
int dostuff(const char *src, char *dest);
int dostuff(const char *src, char *dest, size_t len);
Or even:
int dostuff(std::string src, std::string dest);
All bets are instantly off. You now have two distinct functions, and the compiler has to make each, and has to give each a unique name. So C++ allows (where I believe C doesn't) name mangling, which means those two functions might get translated to _dostuff_cp_cp and _dostuff_cp_cp_s (so that each version of the function that takes a different number of arguments has a different name).
The problem with this is (and I consider this a huge mistake, even though it's not the only problem with cross-compiler portability in C++) that the C++ standard left the details of how to mangle these names up to the compiler. So while one C++ compiler may do that, another may do _cp_cp_s_dostuff, and yet another may do _dostuff_my_compiler_is_teh_coolest_char_ptr_char_ptr_size_t. The problem is exacerbated (always find a way to sneak this word into anything you say or write) by the fact that you have to mangle names for more than just overloaded functions - what about methods and namespaces and method overloading and operator overloading and... (the list goes on). There is only one standard way to ensure that your function's name is actually what you expect it to be in C++:
extern "C" int dostuff(const char *src, char *dest);
Many applications need to have (or at least find it very useful to have) a standard ABI provided by C. Apache, for example, couldn't be nearly as cross-platform and easily extensible if it was in C++ - you'd have to account for the name mangling of a particular compiler (and a particular compiler version - GCC has changed a few times in its history) or require that everyone use the same compiler universally - which means that, every time you upgrade your C++ compiler with a backwards incompatible name-mangling scheme, you have to recompile all your C++ programs.
This post turned into something of a monster, but I think it illustrates a good point, and I'm too tired to try to trim it down.
As someone who dislikes C++ and would pick C over it any day, I can at least give you my impressions on the topic. C++ has several attributes that make it unappealing:
Complicated objects. C++ has tons of ability to speed up OO, which makes the language very complex.
Nonstandard syntax. Even today most C++ compilers support quirks that make ensuring successful and correct compilation between compilers difficult.
Nonstandard libraries. Compared to C libraries, C++ libraries are not nearly as standardized across systems. Having had to deal with Make issues associated with this before I can tell you that going with C is a big time saver.
That said, C++ does have the benefits of supporting objects. But when it comes down to it, even for large projects, modularity can be accomplished without objects. When you add in the fact that essentially every programmer who might contribute code to any project can program C, it seems hard to make the choice to go with anything else if you need to write your code that close to the metal.
All that said, many projects jump over C++ and go to languages like Python, Java, or Ruby because they provide more abstraction and faster development. When you add in their ability to support compiling out to/loading in from C code for parts that need the performance kick, C++ loses what edge it could have had.
If you look at recent open source projects, you'll see many of them use C++. KDE, for instance, has all of its subprojects in C++. But for projects that started a decade ago, it was a risky decision. C was way more standardized at the time, both formally and in practice (compiler implementations). Also C++ depends on a bigger runtime and lacked good libraries at that time. You know that personal preference plays a big role in such decision, and at that time the C workforce in UNIX/Linux projects was far bigger than C++, so the probability that the initial developer(s) for a new project were more comfortable with C was greater. Also, any project that needs to expose an API would do that in C (to avoid ABI problems), so that would be another argument to favor C.
And finally, before smart pointers became popular, it was much more dangerous to program in C++. You'd need more skilled programmers, and they would need to be overly cautions. Although C has the same problems, its simpler data structures are easier to debug using bounds checking tools/libraries.
Also consider that C++ is an option only for high-level code (desktop apps and the like). The kernel, drivers, etc. are not viable candidates for C++ development. C++ has too much "under the hood" behavior (constructor/destructor chains, virtual methods table, etc) and in such projects you need to be sure the resulting machine/assembly code won't have any surprises and doesn't depend on runtime library support to work.
One important aspect in addition to others that will doubtless be mentioned is that C is easier to interface with other languages, so in the case of a library intended to be widely useful, C may be chosen even nowadays for this purpose.
To take examples I am familiar with, the toolkit GTK+ (in C) has robust OCaml bindings, while Qt and Cocoa (respectively in C++ and Objective C) only have proof-of-concepts for such bindings. I believe that the difficulty to interface languages other than C with OCaml is part of the reason.
One reason might be that the GNU coding standards specifically ask you to use C. Another reason I can think of is that the free software tools work better with C than C++. For example, GNU indent doesn't do C++ as well as it does C, or etags doesn't parse C++ as well as it parses C.
I can list a couple more reasons
C code produces more compact object
code. Try to compile 'Hello World'
as C and C++ program and compare the
size of the executable. May not be too relevant today but definitely was a factor 10+ years ago
It is much easier to use dynamic
linking with C programs. Most of
the C++ libraries still expose entry
points through C interface. So instead of writing a bridge between C++ and C why not to program the whole thing in C?
First of all, some of the biggest open source projects are written in C++: Open Office, Firefox, Chrome, MySQL,...
Having said that, there are also many big projects written in C. Reasons vary: they may have been started when C++ was not standardized yet, or the authors are/were more comfortable with C, or they hoped that the easier learning curve for C would attract more contributors.
If correctly implemented C is very fast and very portable and the compilers are there
C++ is different for each compiler available, the libraries dont agree, the standards donĀ“t match.
You can read Dov Bulka to find what not to do in cpp, you can read tesseract ocr at Google code, you can read lots of things - most of which depend on where you are to determine which code linguistic is superior. Where did you read that c has more source code up in open source than cpp? Well of course you read that in a c forum. That's where. Go to some other programming linguistic. Do the same search, you will find that that code has more open source.

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 )