120

Following are the benefits of C++

  • C++ provides the specific features they are asking about
  • Their C compiler is almost certainly really a C++ compiler, so there are no software cost implications
  • C++ is just as portable as C
  • C++ code can be just as efficient as C (or more so, or less so)

Are there any concrete reasons and specific scenarios, where one has to use C over C++?

Reference to this question:Library for generics in C

Not a duplicate, because this question is asking about language limitations and not about should/shouldn't learn one language over another.

Peter Kirkham's post was for me the most informative, particularly with regard to C99 issues which I hadn't considered, so I've accepted it. Thanks to all others who took part.

Ajeet Ganga
  • 8,353
  • 10
  • 56
  • 79
  • Duplicate of http://stackoverflow.com/questions/482574/whats-the-advantage-of-using-c-over-c-or-is-there-one – kgiannakakis Mar 16 '09 at 09:56
  • 13
    It doesn’t matter whether this question is _intended_ to be argumentative or not, it still is. The choice of language for a project is exactly that: a choice. – Bombe Mar 16 '09 at 10:02
  • 8
    @bombe are we not supposed to discuss how to make informed choices? –  Mar 16 '09 at 11:12
  • 5
    DUPLICATE... see: 1. http://stackoverflow.com/questions/145096/is-it-true-that-there-is-no-need-to-learn-c-because-c-contains-everything/145098#145098 2. http://stackoverflow.com/questions/482574/whats-the-advantage-of-using-c-over-c-or-is-there-one – Trevor Boyd Smith Mar 16 '09 at 12:13
  • 3
    3. http://stackoverflow.com/questions/561834/when-do-you-prefer-c-to-c 4. http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57983 5. http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918 – Trevor Boyd Smith Mar 16 '09 at 12:14
  • @orokusaki When I said "generics" in the question, I meant "generics". Note that "generics" and "generic" do not have the same meaning when applied to programming languages. –  Mar 10 '10 at 17:26
  • 10
    Isn't it ironic when you give advice to C programmers to move to C++ that they're about as receptive to your idea, as you would be, if a C programmer told you you should ditch C++ and move to C? – Warren P Jun 14 '10 at 14:45
  • C++ libraries are not portable between compilers. If you are releasing library for Unix, you'd have to compile it at least with g++ and native C++ compiler, and most likely multiple versions of g++ compilers. With C libraries it is not an issue. – Alex Apr 14 '12 at 05:24
  • 2
    There are several language based on C. Why pick C++ over the others? – Keith Thompson Sep 08 '13 at 21:26
  • @WarrenP It isn't. That would be just reciprocal. Ironic would be me trying to explain irony and not knowing what irony is. – Ajeet Ganga Feb 26 '18 at 23:35
  • English is weird. Just because Irony has a formal meaning, doesn't mean the expression "Isn't it ironic" is referring to that formal meaning. Pro-tips. – Warren P Feb 28 '18 at 00:50

31 Answers31

138

This is prompted by a an answer I gave to a current question which asks about a generics library for C - the questioner specifically states that they do not want to use C++.

C is a complete programming language. C is not an arbitrary subset of C++. C is not a subset of C++ at all.

This is valid C:

foo_t* foo = malloc ( sizeof(foo_t) );

To make it compile as C++ you have to write:

foo_t* foo = static_cast<foo_t*>( malloc ( sizeof(foo_t) ) );

which isn't valid C any more. (you could use the C-style cast, it which case it would compile in C, but be shunned by most C++ coding standards, and also by many C programmers; witness the "don't cast malloc" comments all over Stack Overflow).


They are not the same language, and if you have an existing project in C you don't want to rewrite it in a different language just to use a library. You would prefer to use libraries which you can interface to in the language you are working in. (In some cases this is possible with a few extern "C" wrapper functions, depending on how template/inline a C++ library is.)

Taking the first C file in a project I'm working on, this is what happens if you just swap gcc std=c99 for g++:

sandiego:$ g++ -g  -O1 -pedantic -mfpmath=sse -DUSE_SSE2 -DUSE_XMM3  -I src/core -L /usr/lib -DARCH=elf64 -D_BSD_SOURCE -DPOSIX -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -Wall -Wextra -Wwrite-strings -Wredundant-decls -Werror -Isrc  src/core/kin_object.c -c -o obj/kin_object.o | wc -l
In file included from src/core/kin_object.c:22:
src/core/kin_object.h:791:28: error: anonymous variadic macros were introduced in C99
In file included from src/core/kin_object.c:26:
src/core/kin_log.h:42:42: error: anonymous variadic macros were introduced in C99
src/core/kin_log.h:94:29: error: anonymous variadic macros were introduced in C99
...
cc1plus: warnings being treated as errors
src/core/kin_object.c:101: error: ISO C++ does not support the ‘z’ printf length modifier
..
src/core/kin_object.c:160: error: invalid conversion from ‘void*’ to ‘kin_object_t*’
..
src/core/kin_object.c:227: error: unused parameter ‘restrict’
..
src/core/kin_object.c:271: error: ISO C++ does not support the ‘z’ printf length modifier
src/core/kin_object.c:271: error: ISO C++ does not support the ‘z’ printf length modifier

In total 69 lines of errors, four of which are invalid conversions, but mostly for features that exist in C99 but not in C++.

It's not like I'm using those features for the fun of it. It would take significant work to port it to a different language.

So it is plain wrong to suggest that

[a] C compiler is almost certainly really a C++ compiler, so there are no software cost implications

There are often significant cost implications in porting existing C code to the procedural subset of C++.

So suggesting 'use the C++ std::queue class' as an answer to question looking for an library implementation of a queue in C is dafter than suggesting 'use objective C' and 'call the Java java.util.Queue class using JNI' or 'call the CPython library' - Objective C actually is a proper superset of C (including C99), and Java and CPython libraries both are callable directly from C without having to port unrelated code to the C++ language.

Of course you could supply a C façade to the C++ library, but once you're doing that C++ is no different to Java or Python.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
  • 1
    I agree with most of what you say but a C-style cast with malloc e.g. int * p = (int *)malloc( 32 ) compiles without a warning under gcc with -pedandtic and -std=c99 –  Mar 16 '09 at 14:24
  • 22
    Yes. C-style cast is quite usual when you use malloc. When using malloc you do it do stay within the c subset. If you want to program C++ style, you would use operator new, not static_cast + malloc. – Suma Mar 16 '09 at 19:15
  • 35
    Saying that C is not a subset of C++ is incredibly pedantic. Sure, you could say that any struct with a member called "class" will not compile, but it's really only minor modifications that are required, and most compilers have options to add the few C-only features to C++. – Kaz Dragon Mar 18 '09 at 15:44
  • 29
    as far as your malloc example goes, adding a cast wouldn't just be shunned by C++ programmers, but also (especially) by C programmers. There are good reasons to leave out the cast in C code. It's not necessary, and adding it may conceal errors. So yeah, treat them as two distinct languages. +1 :) – jalf Mar 18 '09 at 16:19
  • 27
    @BlueRaja Imagine if Guido had decided not to add objects to his scripting language, and two groups had created mutually incompatible forks of Python to add objects, one with an object model based on Smalltalk, the other with a class system based on Simula. Then Guido continued to improve Python focussing its core use. That's closer to the C/Objective C/C++ situation. – Pete Kirkham Jan 29 '10 at 09:27
  • 12
    @BlueRaja: They're two distinct languages that share a fairly large common core. If you program in that common core, you're going to wind up doing things that aren't good code in either language. Pick one language to write any given program in, and make it good in that language. – David Thornley Mar 10 '10 at 17:30
  • 3
    Objective-C is a proper superset of C99 if you compile it with `-std=c99` – JeremyP Mar 11 '11 at 09:53
  • Actually Objective-C is just a simple mix of C and modified Smalltalk, and you can use `-ansi` or `-std=c99` or `std=c11` to choose a version of C to be mixed in. I have quite a number of Objective-C projects that makes heavy use of C99 features and my upcoming projects will even call for C11. – Maxthon Chan Aug 06 '13 at 05:42
  • 3
    @KazDragon Can you figure out a way to compile a C source file that calls methods and use objects from C++? I know by (ab)using Objective-C runtime library you can not only use ObjC objects and call methods, you can even declare new classes and so. Also, some (all) Objective-C language structs are just syntax candy that can be replaced with a C `#define`, e.g. `@class NSString` is just `typedef struct objc_object NSString` – Maxthon Chan Aug 06 '13 at 05:47
  • 1
    -1, me and Bjarne think that C is a subset of C++. Ofc you could say Bjarne doesnt know what he is talking about, but expert like me you cant ignore :P – NoSenseEtAl Aug 06 '13 at 06:26
  • 1
    @MaxthonChan Not directly, but you can certainly create yourself C-like structures that are exported from C++ code and callable from C. Every problem being solvable by a layer of indirection, as you know. But I think that gets away somewhat from the spirit of this response. – Kaz Dragon Aug 06 '13 at 07:34
  • 1
    @KazDragon Well I mean directly - no indirection whatsoever. When I need a queue (using the example in the answer) I will go ahead `alloc`/`init` an `NSMutableArray` - just rewrite Objective-C code `[[NSMutableArray alloc] init]` into what compiler generates under the hood, `id queue = objc_msgSend(objc_msgSend(objc_getClass("NSMutableArray"), sel_registerName("alloc")), sel_registerName("init"))` and after done, `objc_release(queue)` it and link libobjc and Foundation (GNUstep-base for Linux) to my binary. – Maxthon Chan Aug 06 '13 at 08:36
  • @MaxthonChan I still don't see what you're getting at. My point was that you can, with very few changes, write a subset of C++ code that is compileable in a C compiler. That is, the "it's not a subset" argument is quite weak. It was not that you can write *all* C++ code to be usable from a C compiler. – Kaz Dragon Aug 06 '13 at 10:30
  • 1
    @KazDragon The point is "rename and compile" - for C++ `mv test.c test.cc` and `clang++ test.cc -c` may not work, but for Objective-C `mv test.c test.m` and `clang test.c -c` will guarantee to work. (My preferred C/C++/ObjC compiler is clang.) – Maxthon Chan Aug 06 '13 at 10:35
  • Ok. And? I don't see how that invalidates what I said four years ago. Your point is that Objective C is a better C superset than C++? Ok, granted. – Kaz Dragon Aug 06 '13 at 10:45
  • 5
    @NoSenseEtAl I give an example of the result of compiling some C99 code with a C++ compiler. You cannot compile all valid C constructs as C++, ergo C is not a subset of C++ (with the current C++0x standard, though I'm not sure if literal object initialisers will go into C++ in a compatible form). I prefer empirical demonstrations over appeals to authority. – Pete Kirkham Aug 06 '13 at 12:58
  • 6
    @KazDragon No, it isn't incredibly pedantic. I like and often use some features of C which make my C code fail to compile with a C++ compiler. C is not a subset of C++ and it never was. Asserting that fact is not "extremely pedantic". Maybe you don't know C or C++ or both well enough to realize that there are **huge** differences, but regardless of that, there are. –  Sep 08 '13 at 21:20
  • 3
    @NoSenseEtAl The same applies to your comment. And you are extremely wrong in that "Bjarne thinks that C is a subset of C++". Stroustrup never said that. He only sad that he was "arguing for strong compatibility from the beginnings". He failed. C and C++ do share a common subset (some misled guys like to call it "pure C"), but it's definitely not the case that C is a subset of C++. –  Sep 08 '13 at 21:22
  • @KazDragon: the most recent thing I ran into that C++ is missing is C99-style variable-length arrays. I wanted a small array on the stack for performance reasons, like `__m256 cached_division_results[n]`, which compiles fine in GNU C++ (where VLAs are a GNU extension), but for compat with MSVC I ended up using `new` / `delete`. I could have used `alloca`, but that would have been uglier. – Peter Cordes Feb 26 '18 at 00:56
  • @PeterCordes: How often is there a real advantage to using a variable-sized array on the stack versus using an array of fixed maximum size, or perhaps having a few wrapper functions which create automatic arrays of various sizes and then pass them to a common core function? – supercat Jul 26 '18 at 16:05
  • @supercat: The page / cache lines around the stack pointer are typically hot in cache / TLB. If your worst-case size is like 1MB vs. a normal size of under 1kB, always using the max size will put you way outside the range of "hot" stack memory and incur some cache misses and a TLB miss. (And a page fault the first time). In my case the `_mm_malloc` / `_mm_free` (for alignment) overhead was trivial compared to the run-time of the loop that reused it, but if my typical input size had been smaller then startup / cleanup overhead would start to matter. (x/y pairs -> bitmap of in/outside polygon) – Peter Cordes Jul 26 '18 at 16:12
  • @Suma wrote: *If you want to program C++ style, you would use operator new, not static_cast + malloc*. Important to note that `new` isn't guaranteed to be compatible with `free`, nor `malloc` with `delete`. They are on GNU/Linux with gcc+glibc, but not on MSVC, so if you're passing memory to a C library that wants to free it, you must use `malloc` (or `calloc` or `realloc`) regardless of the coding style of the rest of the caller. – Peter Cordes Jul 26 '18 at 16:27
119

I realize it's neither a professional nor a particular good answer, but for me it's simply because I really like C. C is small and simple and I can fit the whole language in my brain, C++ to me has always seemed like a huge sprawling mess with all kinds of layers I have a hard time grokking. Due to this I find that whenever I write C++ I end up spending far more time debugging and banging my head against hard surfaces than when I code C. Again I realize that a lot of this is largely a result of my own 'ignorance'.

If I get to choose I'll write all the high level stuff like the interface and database interaction in python (or possibly C#) and all the stuff that has to be fast in C. To me that gives me the best of all worlds. Writing everything in C++ feels like getting the worst of all worlds.

Edit: I'd like to add that I think C with a few C++ features is largely a bad idea if you're going to be several people working on a project or if maintainability is priority. There will be disagreement as to what constitutes a 'a few' and which bits should be done in C and which bits in C++ leading eventually to a very schizophrenic codebase.

ApprenticeHacker
  • 21,351
  • 27
  • 103
  • 153
dagw
  • 2,568
  • 4
  • 20
  • 21
  • 26
    I used C++ for several years and still spent 50% of my time refactoring code to be "C++ correct". It's a nightmare, as you say. – Kai Jun 16 '09 at 14:50
  • 13
    You could always just do it right the first time. Adding const isn't difficult. – GManNickG Jul 18 '09 at 19:56
  • 16
    I used C++ for ten years, and going back to C (for embedded systems in my case) was the best thing I ever did. – Warren P Jun 14 '10 at 14:37
  • I love this answer. You've nailed my feelings too. I've had years of work as a C++ dev, my day job is *still* C++. But that doesn't mean I like the language, I see beauty in C. – Matt Joiner Nov 15 '10 at 02:44
  • 13
    +1, _Due to this I find that whenever I write C++ I end up spending far more time debugging and banging my head against hard surfaces than when I code C_ . Can't agree with you more. The best answer. :) – ApprenticeHacker Mar 17 '12 at 08:56
  • I would argue that is indeed professional to use the tools that you know if it gets the task done. Professional just mean you get paid for doing the task. – rxantos Oct 31 '17 at 02:40
60

C++ simply isn't supported in some real-world environments, like low-level embedded systems. And there's a good reason for that: C easily good enough for such things, so why use something bigger?

Joonas Pulakka
  • 36,252
  • 29
  • 106
  • 169
40

A couple of reasons might be:

  • Lack of support - Not every C compiler is also a C++ compiler. Not all compilers are particularly compliant with the standard, even if they claim to support C++. And some C++ compilers generate hopelessly bloated and inefficient code. Some compilers have terrible implementations of the standard library. Kernel-mode development generally makes use of the C++ standard library impossible, as well as some language features. You can still write C++ code if you stick to the core of the language, but then it may be simpler to switch to C.
  • Familiarity. C++ is a complex language. It's easier to teach someone C than C++, and it's easier to find a good C programmer than a good C++ programmer. (keyword here is "good". There are plenty of C++ programmers, but most of them have not learned the language properly)
  • Learning curve - As above, teaching someone C++ is a huge task. If you're writing an app that has to be maintained by others in the future, and these others may not be C++ programmers, writing it in C makes it a lot easier to get to grips with.

I'd still prefer writing in C++ when I can get away with it, and overall, I think the benefits outweigh the disadvantages. But I can also see the argument for using C in some cases.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • 5
    I would add that C code compiles much faster than C++. A huge project at our company (more than one million lines) compiles less than 30 second. – Calmarius Oct 25 '11 at 17:19
  • 1
    @Calmarius For most programmers through, Runtime tends to be more of a problem than Compilation time :) – Yunfei Chen Feb 21 '21 at 23:02
33

There are loads of arguments about embedded programming, performance and stuff, I don't buy them. C++ easily compares to C in those areas. However:

Just recently after having programmed in C++ for over 15 years I've been rediscovering my C roots. I must say that while there are good features in C++ that makes life easier there are also a load of pitfalls and a kind of "there-is-always-a-better-way" of doing things. You never actually get quite happy about the solution you did. (Don't get me wrong, this could be a good thing, but mostly not).

C++ gives you infinite gunfire. Which could be arguably good but somehow you always end up using too much of it. This means that you are disguising your solutions with "nice" and "pretty" layers of abstractions, generality, etc.

What I discovered going back to C was that it was actually fun programming again. Having spent so much time modeling and thinking about how to best use inheritance I find that programming in C actually makes my source code smaller and more readable. This is of course depending on you level of self-discipline. But it is very easy to put too much abstractions on straight forward code, which is never actually needed.

Anders Hansson
  • 3,746
  • 3
  • 28
  • 27
  • 9
    No offense, but it might also depend on what you think C++ is. Inheritance is something I associate more with Java than C++, and if you treat C++ strictly as an OOP language á la Java (C with classes), then I agree with you. If you stick with a more modern flavor of C++, I think it's more fun than C – jalf Mar 16 '09 at 16:11
  • No offense taken; although I don't think of C++ as C with classes. Inheritance was just an example. It is a different language and should be treated as such. Nevertheless, I find C++ projects all too often containing unnecessary code just to follow some OO paradigm. – Anders Hansson Mar 16 '09 at 18:45
  • 12
    Once again though, I don't think of C++ as an OO language, and it shouldn't be treated as one. I think generic programming is a much stronger trait of C++. Most of the C++ code I see doesn't try particularly hard to be "OO", or contain unnecessary code. It's often leaner than the equivalent C code – jalf Mar 16 '09 at 22:40
  • 1
    In any case, +1 from me. It answers the OP's question, and I can see where you're coming from. I just think taking a different perspective on C++ would solve the problem as well :) – jalf Mar 16 '09 at 22:41
  • 4
    @jalf: Another thing that I find can become a "there-is-always-a-better-way" distraction in C++ is generalising things with templates. "Maybe we should let the user of this class decide what underlying integer type to use?" But you probably don't *need* that, and in C you wouldn't bother. And sometimes I find myself thinking, "We should really provide a forward iterator interface to this class," when in C you would just expose a pointer to the first element and a count, or (the height of fanciness!) a function taking a callback function pointer. – j_random_hacker Jul 06 '10 at 00:45
  • 3
    I find taking a step back when coding in C++ helps. Decide the goal, and write towards it (C style). Factor in C++isms as their usefulness becomes apparent. – Matt Joiner Nov 15 '10 at 02:46
  • Agree with you. I'm used to work with either C or C++ projects, and I can easier build nice C design then C++ one, which is always looks "not so good". And even it looks good enough, some times later it starts to look terrible. – Yury Jul 06 '12 at 06:40
  • 2
    `infinite gunfire`, ooh yeah, so true. Our feet literally tremble :) – quetzalcoatl Aug 06 '13 at 06:33
27

C has the main advantage that you can just see what is really going on when you look at some piece of code (yeah preprocessor: compile with -E and then you see it). Something that is far too often not true when you look at some C++ code. There you have constructors and destructors that get called implicitly based on scope or due to assignments, you have operator overloading that can have surprising behavior even when it's not badly misused. I admit I'm a control freak, but I have come to the conclusion that this is not such a bad habit for a software developer who wants to write reliable software. I just want to have a fair chance to say that my software does exactly what it is supposed to do and not have a bad feeling in my stomach at the same time because I know there could still be so many bugs in it that I wouldn't even notice when I looked at the code that causes them.

C++ also has templates. I hate and love them, but if anyone says he or she fully understands them I call him/her a liar! That includes the compiler writers as well as the folks involved in defining the standard (which becomes obvious when you try to read it). There are so many absurdly misleading corner cases involved that it's simply not possible to consider them all while you write actual code. I love C++ templates for their sheer power. It's really amazing what you can do with them, but they can likewise lead to the strangest and hardest to find errors one can (not) imagine. And these errors actually happen and not even rarely. Reading about the rules involved to resolve templates in the C++ ARM almost makes my head explode. And it gives me the bad feeling of wasted time having to read compiler error messages that are several 1000 characters long for which I need already 10 minutes or more to understand what the compiler actually wants from me. In typical C++ (library) code you also often find a lot of code in header files to make certain templates possible which in turn makes compile/execute cycles painfully slow even on fast machines and requires recompilation of large parts of the code when you change something there.

C++ also has the const trap. You either avoid const for all but the most trivial use cases or you will sooner or later have to cast it away or to refactor large parts of the code base when it evolves, especially when you are about to develop a nice and flexible OO design.

C++ has stronger typing than C, which is great, but sometimes I feel like I'm feeding a Tamagotchi when I try to compile C++ code. A large part of the warnings and errors I usually get from it are not really me doing something that wouldn't work, but just things the compiler doesn't like me to do this way or not without casting or putting some extra keywords here and there.

These are just some of the reasons why I don't like C++ for software that I write alone only using some allegedly robust external libraries. The real horror begins when you write code in teams with other people. It almost doesn't matter whether they are very clever C++ hackers or naive beginners. Everybody makes errors, but C++ makes it deliberately hard to find them and even harder to spot them before they happen.

With C++ you are simply lost without using a debugger all the time but I like to be able to verify the correctness of my code in my head and not having to rely on a debugger to find my code running on paths I would never have anticipated. I actually try to run all my code in my head and try to take all the branches it has, even in subroutines etc. and to use a debugger only occasionally just to see how nicely it runs through all the cosy places I prepared for it. Writing and executing so many test cases that all code paths have been used in all combinations with all sorts of strange input data is simply impossible. So you might not know of the bugs in C++ programs but that doesn't mean they are not there. The larger a C++ projects gets the lower becomes my confidence that it will not have lots of undetected bugs even if it runs perfectly with all the test data we have at hand. Eventually I trash it and start anew with some other language or combination of other languages.

I could go on but I guess I made my point clear by now. All of this has made me feel unproductive when I program in C++ and made me lose confidence in the correctness of my own code which means I won't use it anymore, while I still use and rely on C code that I wrote more than 20 years ago. Maybe it's simply because I'm not a good C++ programmer, or maybe being quite good in C and other languages allows me to recognize what a lamer I actually am when it comes to C++, and that I will never be able to fully comprehend it.

Life is short...

Jason Plank
  • 2,336
  • 5
  • 31
  • 40
x4u
  • 13,877
  • 6
  • 48
  • 58
  • 1
    "but I like to be able to verify the correctness of my code in my head and not having to rely on a debugger to find my code running on paths I would never have anticipated." Sometimes those paths that you never have anticipated can crash the program when you release it into production code because you never know who gonna use it and what they are going to use it for. – Yunfei Chen Feb 21 '21 at 23:07
24

In a low-level embedded environment some of the "software engineers" will have an EE background and have barely mastered C. C++ is more complex and some of these guys are simply afraid to learn a new language. Thus C is used as the lowest common denominator. (Before you suggest getting rid of these guys, they're at least as important as the CS majors who don't understand the hardcore analog stuff.)

Speaking from experience in having inherited and maintained both: a horrible design in C is difficult to understand, unwind, and refactor into something usable.

A horrible design in C++ is infinitely worse as random layers of abstraction send your brain careening around the codebase trying to figure out which code is going to be executed in which circumstance.

If I have to work with engineers who I know will not produce great designs, I'd much rather have the former than the latter.

bstpierre
  • 30,042
  • 15
  • 70
  • 103
  • Amen, brother. Having worked with C source produced by hardware engineers I shudder to think of what I would be faced with if they had done it in C++. – Richard Chambers Sep 08 '13 at 18:17
  • "If I have to work with engineers who I know will not produce great designs, I'd much rather have the former than the latter." Those enginners should not be engineers at all, they should be janitors, why did you hire them in the first place?? – Yunfei Chen Feb 21 '21 at 23:09
21

I do not see any reason other then personal dislike, even for programming embedded systems and similar things. In C++ you pay overhead only for features you use. You can use the C subset of the C++ in some specific situations where C++ overhead is too high for you. This said, I think some C programmers overestimate the overhead of some C++ constructs. Let me list some examples:

  • Classes and member functions have zero overhead compared to normal functions (unless you use virtual functions, in which case there is no overhead compared to using functions pointers)
  • Templates have very little overhead (most often no overhead at all)

One valid reason would be when you are programming for a platform which does not have a decent C++ compiler (no C++ compiler at all, or a compiler exists, but is poorly implemented and imposes an unnecessary high overhead for some C++ features).

Suma
  • 33,181
  • 16
  • 123
  • 191
  • 3
    A class with virtual functions has more overhead: each instance has to carry around an extra field to identify the type. – bstpierre Mar 16 '09 at 12:07
  • 6
    More overhead than what? The type is carried in the vtbl. If you implement similar mechanism using function pointers, you need at least one pointer (or index, or whatever) to select the function pointer you want to be used. – Suma Mar 16 '09 at 12:54
  • 4
    bstpierre: I think what Suma is saying is: that it has no more overhead than implementing the feature manually yourself in C. – Martin York Mar 16 '09 at 14:46
  • 2
    A pointer to the classes vtable is stored in each instance of the class. – tstenner Apr 12 '09 at 16:27
  • 5
    There is an overhead, but what I mean is that if you want any dynamic type resolution, you need some storage to identify the type, even in C. If you do not want the dynamic types, you do not need to pay the overhead (do not use virtual functions if you do not need them). – Suma Apr 12 '09 at 19:31
  • 3
    This virtual function thing is a total sidetrack. The claim in Suma's post is that "you pay overhead only for features you use". If you don't use virtual functions, you don't pay the overhead. If you can't live with the overhead, don't use them. – Jason Orendorff Apr 10 '10 at 21:13
  • Exceptions are also more costly than simple returns. This may matter in some embedded situations. Also binary size and runtime may be critical. – Prof. Falken Apr 13 '10 at 14:19
  • Again - you are not forced to use exception in C++. You can stay with return values. (I am a game developer and we never use exception handling in our games, as the performance cost of it is too high for us) – Suma Apr 13 '10 at 19:43
15

Why limit speaking in English? Perhaps you'd be a more creative author in Serbian.

That's the same argument, with obvious fallacies. If you have a task, and your comfortable tools solve the task efficiently, you'll likely use your comfortable tools for good reason.

SPWorley
  • 11,550
  • 9
  • 43
  • 63
  • 3
    If I spoke both fluent English and fluent Serbian, I'm sure I would be more creative. Do you disagree? –  Mar 16 '09 at 12:00
  • 2
    @Neil indeed, but the effort required to learn Serbian might not be justified to solve my current creativity block. – slim Mar 16 '09 at 14:03
  • 3
    I think Arno is highlighting the fact that you're not writing for the CPU, you're writing for your coworkers to read, and your other libraries to link, and so on. After all, if I was just going for expressivity and speed, I'd write in OCaml. – Ken Jan 16 '10 at 17:37
13

C++ has a much longer learning curve. C has only few constructs you need to be aware of and then you can start coding powerful software. In C++ you need to learn the C base, then the OO and generic programming, exception, etc. And after a time you may know most of the features and you porbably can use them, but you still don't know how the compiler will translate them, what implicit overhead they have or not. This takes much time and energy.

For a professional project this argument may not count, because you can employ people that already know C++ very well. But in Open Source Projects, where C is still widley used, the people pick the language they like and they are able to use. Consider that not every OS-programmer is a professional programmer.

quinmars
  • 11,175
  • 8
  • 32
  • 41
  • 1
    Erm... no? You learn the C base (possibly with the exception of arrays and C-style string handling dropped in favor of and ), and you get going. You can pick up everything else as you go along. You don't have to know anything about OO, GP, or exceptions to get started with C++... – DevSolar Mar 16 '09 at 11:07
  • 4
    C may be "smaller" but in the long term it isn't easier to use. Manual memory management? No thanks. – Jimmy J Mar 16 '09 at 11:33
  • 7
    There ain't no such thing as automatic memory management in C++. – Warren P Jun 18 '10 at 13:41
  • 3
    C++ doesn't solve the memory management problem. Just when you thought you had a handle on pointers, C++ goes and adds an awful exception model. Come to C99 land, Except for data structures, I'm pretty certain I barely touch malloc. Even then I can "encapsulate" a handful of malloc calls. It's much the same story in C++ (implicit memory management, only its done on the heap instead of the stack), only with all the smart pointer jazz. – Matt Joiner Nov 15 '10 at 02:50
  • 1
    @MattJoiner: Not sure I follow the "Only its done on the heap" part. – ereOn Aug 06 '13 at 06:32
  • @ereOn: I mean that implicit memory management in C++ is achieved through use of exception safe containers that allocate to the heap. In C, this is done by allocating on the heap whereever possible. – Matt Joiner Aug 06 '13 at 15:33
  • 1
    @MattJoiner: C++ has containers that can use the stack too. It's up to the user to make the decision. Not sure it is really different from C in that regard. – ereOn Aug 07 '13 at 11:00
  • 1
    @ereOn: It's true, the comment as I wrote it 3 years ago no longer holds. :) – Matt Joiner Aug 08 '13 at 02:24
11

I use C, or at least export a C interface when I write library code.

I don't want ill-defined ABI hassles.

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
  • 1
    Same. Strict C in interfaces only. The last thing I want is someone else's ridiculous object framework pushed on me. – Matt Joiner Nov 15 '10 at 02:55
11

I'd like to follow up on Dan Olson's answer. I believe that people fear the potentially dangerous and counter-productive features of C++, and justifiably so. But unlike what Dan says, I do not think that simply deciding on a coding standard is effective, for two reasons:

  1. Coding standards can be difficult to strictly enforce
  2. It can be very difficult to come up with a good one.

I think that the second reason here is much more important than the first, because deciding on a coding standard can easily become a political matter and be subject to revision later on. Consider the following simplified case:

  1. You're allowed to use stl containers, but not to use templates in any of your own code.
  2. People start complaining that they'd be more productive if they just were allowed to code this or that template class.
  3. Coding standard is revised to allow that.
  4. Slide a slope to an overly complicated coding standard that nobody follows and use of exactly the kind of dangerous code that the standard was supposed to prevent, combined with excess bureaucracy surrounding the standard.

(The alternative that the standard is not revised in step 3 is empirically too improbable to consider and wouldn't be that much better anyway.)

Though I used to use C++ for just about everything a few years ago, I'm beginning to strongly feel that C is preferrable in low-level tasks that need to be handled by either C or C++ and everything else should be done in some other language entirely. (Only possible exceptions being some specific high-performance problem domains, wrt. Blitz++)

TrayMan
  • 7,180
  • 3
  • 24
  • 33
10

One point I've not seen raised yet, which I think is the most important:

Most of the libraries I use on a daily basis are C libraries with bindings for Python, Ruby, Perl, Java, etc. From what I've seen, it's a lot easier to wrap C libraries with 19 different language bindings than it is to wrap C++ libraries.

For example, I learned Cairo once, and have since used it in 3 or 4 different languages. Big win! I'd rather write a program that can be used again in the future, and writing one that can easily be adopted to other programming languages is an extreme case of this.

I know it's possible to bind C++ libraries, but AFAICT it's not the same. I've used Qt (v3 and v4) in other languages and it's not anywhere near as nice to use: they feel like writing C++ in some other language, not like native libraries. (You have to pass C++ method sigs as strings!)

C++ is probably a better language if you're writing a function to be used once, or if you think all the world is C++. C seems like an easier language if you're designing for language-portability from the start.

Ken
  • 437
  • 7
  • 10
  • The "pass methods as strings!" thing is a defect of Qt, not C++. You could actually have the same stupid mechanism with a C framework would you want to. Even the guys at Qt agree that doing that was a mistake. There was just no better alternative in their mind at the time and it was too late to change it back when they realized. – ereOn Aug 06 '13 at 06:36
10

I've never seen any arguments for using C over C++ that I'd consider convincing. I think most people are afraid of certain features C++ offers, often justifiably. Yet this doesn't convince me because one can enforce whether or not to use certain features through coding standards. Even in C, there's much you'd want to avoid. Discarding C++ entirely is essentially saying it offers no tangible benefits over C that would help one write better code, which is a view I consider to be quite ignorant.

Additionally, people always seem to raise the situation of platforms where no C++ compiler exists. Certainly C would be appropriate here, but I think you'd be hard pressed to find a platform like that these days.

Dan Olson
  • 22,849
  • 4
  • 42
  • 56
  • 3
    Agreed, the "C is better than C++" rants never stand up to scrutiny. – Jimmy J Mar 16 '09 at 11:27
  • 8
    I believe C++ offers me VERY LITTLE benefit, and COSTS ME a huge amount of accidental complexity. I believe it would take about 1500 pages of C++ textbooks, and ten years of effort, to become as proficient in C++ as I currently am in C, Pascal, Python, and Objective-C. Each of the above languages is about 20x more orthogonal, compact, and mentally convenient to use, not to mention more powerful, in the environments where I use them. There are simply NO rationally justifiable uses for C++ in my usual development environments. – Warren P Jun 14 '10 at 14:39
  • 1
    @Warren You only pay for what you use, just like any language. If you're not capable of deciding how to code wisely in C++ that's on you, not the language. – Dan Olson Jun 16 '10 at 03:27
  • 2
    Not so. If you are the only developer on a project, that might be so. But as soon as we have two developers, we have battles. What? You insist on IoC containers, whereas I prefer some other way of doing delegates... You like three levels of nested templates, and I prefer zero templates. A mess. – Warren P Jun 18 '10 at 13:40
  • I know this post is 10 years old but is it really fair to even compare C and C++ anymore? They're both separate, diverged languages (since C99) and they both have their benefits and drawbacks that each one covers. C++ is difficult to debug and maintain? C's explicitness let's you debug better. C doesn't have generics? C++ has generics! At this point in time, no language is better than the other. – Nergal Feb 08 '19 at 23:52
  • "C's explicitness let's you debug better." Not really, it usually results in Code that is impossible to debug because it is also 10x longer.... with pointer to pointers to pointers to god knows what..... :( – Yunfei Chen Feb 21 '21 at 23:18
  • 1
    @WarrenP the advantage of C++ is that you have a high performance language while you have code that is easy to read, the downside of C is that a lot of times the explict declarations are so long that you can write an equally effecient solution in C++ in 10x less code, and Python?? I won't say much but by the time Python finishes interpreting my real-time programmers, I will have rewritten the entire program in C and C++ already.... If it can actually finish running... – Yunfei Chen Feb 21 '21 at 23:22
8

Windows kernel development doesn't support c++ (sadly).

LegendLength
  • 473
  • 3
  • 11
  • How is that? Why? Is the binary produced from a C++ compiler different from a C compiler? Isn't driver development simply adhering to API's? – Dave Van den Eynde Mar 16 '09 at 10:48
  • 4
    Because a lot of C++ features require runtime support which may not be trivial to implement in kernel-mode. For one thing, different memory allocation functions are used, so chunks of the standard library would have to be replaced. Exceptions are generally bad too. – jalf Mar 16 '09 at 11:29
  • 4
    I'll add that Linux Torvalds fortunately torched any chance of C++ in Linux for more reason than exceptions. There have been a few OS in other languages: Java, C++, assembler. Only the assembler ones have survived with reasonable usage. – Matt Joiner Nov 15 '10 at 02:54
  • -1 http://msdn.microsoft.com/en-us/library/vstudio/jj620896.aspx – NoSenseEtAl Aug 06 '13 at 06:28
  • Notice it's for Visual Studio 2015? – LegendLength Jan 05 '16 at 09:56
  • @LegendLength VSC is excellent to use, I dont know what you have against it?? – Yunfei Chen Feb 21 '21 at 23:24
  • @MattJoiner Linus Torvalds, most of that is rant with zero logic to all through like a three year old saying we shouldn't use addition because he says so !!! – Yunfei Chen Feb 21 '21 at 23:25
7

You can read an entertaining rant about why Linus Torvalds favours C here

Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
  • 7
    It's more of a half-coherent rant against object-oriented design than a rant against C++. – Dan Olson Mar 16 '09 at 10:10
  • ...and if you study the LKML FAQ regarding C++, you will notice it's more about xenophobia than about facts. – DevSolar Mar 16 '09 at 11:04
  • 17
    Mr Torvalds has a long list of things he doesn't like, C++, emacs, Subversion, OO to mention a few. One sometimes wishes he would button his lip a little more –  Mar 16 '09 at 11:15
  • 12
    Linus likes to rant and try to provoke and upset people. Unfortunately, he hasn't bothered to *learn* C++ before declaring that it sucks. Unfortunately, his cult following believe that everything he says must be true. – jalf Mar 16 '09 at 11:31
  • 9
    The link was more for entertainment than education – Paul Dixon Mar 16 '09 at 11:31
  • 6
    Proof that even geniuses can sometimes be dolts. – Kaz Dragon Mar 18 '09 at 15:46
  • 1
    The half-coherent rant is a Linus trademark... – Norman Ramsey May 21 '09 at 23:50
  • 5
    You have to understand the space Linus lives. Anyone who has not done kernel programming does not understand the constraints involved. – Einstein Jan 16 '10 at 19:38
  • 3
    Can't argue with someone who starts his posting with "*YOU* are full of bullshit." :) – Michael Stum Jan 21 '10 at 01:40
  • 1
    Linus built his kernel in C because that's how unix kernels are built. Linus' way of designing kernels and the C++ version of OOP are non-mixable. Name one Operating System Kernel written in pure C++ without any ANSI C modules? Okay. I think it's hilarious that his argument against OOP is that it makes it harder for him to use grep "long_function_name_here". – Warren P Jun 14 '10 at 14:42
6

Native code on a mac is objective-c. Native code on a PC is c (window.h) or c++ (mfc). Both of these environments will let you use c with little or no changes. When I want a library of code to be cross platform ansi c seems like a good choice.

Nick Van Brunt
  • 15,244
  • 11
  • 66
  • 92
5
  1. C is a simple language, C++ is not. For many people, C++ is simply too complicated to fully master, see http://en.wikipedia.org/wiki/C%2B%2B#Criticism.

  2. Because of the complexity, different programmers usually only master different subsets of the language. It makes reading other people's code painful.

  3. The complexity, pitfalls of the language add too much distraction, and sometimes hurt productivity. Instead of focus on the job itself, I often found myself fighting with the language itself. Java/python are more productive alternatives.

  4. Debugging a broken C code is usually much more straightforward than debugging a broken C++ code.

  5. Unlike Java/C#, the C++ standard library achieves little beyond the scope of the C standard library.

  6. Some famous programmers like Linus Torvalds (Linux) and Richard Stallman (Emacs) dislike C++.

Alan Bradley
  • 31
  • 1
  • 1
4

I can think of several reasons.

There may not be a satisfactory C++ compiler. C++ is a much bigger language, and I've run C compilers on systems that would not be able to handle modern C++.

The questioner, or people he or she works with, may be familiar with C but not C++.

The project may be in C. While it's possible to add some C++ features to C, that can easily lead to an unmaintainable mess. I'd suggest picking one language or the other (usually C++, when practical).

The questioner may have an obsolete view of C++'s learning curve. (When approached correctly, it's easier than C's. Most introductory books I've seen don't approach it correctly.)

Remember that C and C++ are two different languages, and are getting more different over time. Coding in both at once is a bad idea, and using a C-like subset of C++ misses most of the advantages of C++.

David Thornley
  • 56,304
  • 9
  • 91
  • 158
3

I can follow many suggestions here in both directions. But in the end it comes down to a) comparable simple b) comparable complex.

I don't have an idea if someone has "invented" a sort of language complexity measurement.

On a scale from 0 - 10 I probably would rate C at 2 or 3 whereas C++ would be between 8-10. I'd argue C++ is one of the most complex languages but I do not know e.g Ada, PL1 or the like, so maybe it's not that complex in comparison to some other language.

C++ inherits all complexity of C so it can not be below the complexity level of C.

I for my part would be much more comfortable using some scripting language and C. So in the end one has to answer the following question. "Is more always better?"

Friedrich
  • 5,916
  • 25
  • 45
3

I use C++ with C programming for two reasons:

  • vector and string to get the array memory management away from me
  • strict type checking and casts to warn and/or catch allthe nuisances I would miss otherwise.

So it is C really borrowing a few c++ but using the c++ compiler as much as I can. As someone else says in the answers, I find now I am actually picking up more C++ this way and where C would be too involving, I use C++. Monitor/Lock using RAII is one of these I've used recently when dealing with multi-threaded programs and another similar construct to open/close files.

dubnde
  • 4,359
  • 9
  • 43
  • 63
3

I think C is more portable. I did some work about 5 years ago porting code to many flavours of unix (AIX,Irix,HPUX,Linux). The C code was easy to port but we had various problems porting some of the C++ code across. Maybe it was just immature development environments but i would much rather use C over C++ for this reason...

Gordon Thompson
  • 4,764
  • 8
  • 48
  • 62
  • 1
    Fifteen years ago I was the lead developer for a C++ project targetting HPUX, AIX and Solaris. We had very few C++ portability problems - almost all the ones we did have were with the C system call incompatibilities. –  Mar 16 '09 at 16:20
  • 1
    Less than ten years ago, I was on a project using HPUX, Solaris, and Tru64, using the traditional compilers. Our nightlies never built. When we added AIX, we decided to switch to standard C++. – David Thornley Mar 16 '09 at 16:31
  • Maybe the people who wrote your code were better coders than the crap i had to deal with :-) – Gordon Thompson Mar 16 '09 at 16:48
2

There are three reasons I can think of. One is that C is more suited for embedded systems, due to the small size of its binaries and the wider availability of C compilers on any system. The second is portability: C is a smaller language, and and ANSI C code will compile anywhere. It's easier to break portability in C++. The last one is the language itself. C++ is harder, and is most definitely a very poorly designed language. Torvalds gripes are reported above. You may also want to look at the C++ Frequently Questioned Answers (http://yosefk.com/c++fqa/).

  • 6
    And, if you're intelligent, after looking at the FQA you'll realize it's a hack job by somebody who doesn't really understand C++ but hates it anyway. – David Thornley Mar 10 '10 at 17:26
2

If you work in an environment with two languages, you might use C for some performance critical low-level functions and a more functional/high level language like C#/Java for the business logic. If C++ code is usedfor these functions ,C-Wrappers are required for JNI/unmanaged code around and this makes things more complex than solely using C.

weismat
  • 7,195
  • 3
  • 43
  • 58
1

The most useful thing I found in C is the lack of namespaces and overloads: function and symbol names are unique identifiers. To find the places where these symbols are used you can just grep through the source code files and search results will shows the locations.

It's essential when wiring in a new feature or component to an old and tangled system.

You cannot do this easily in C++, without a sophisticated call graph building tool.

Calmarius
  • 18,570
  • 18
  • 110
  • 157
1

The following are all reasons why it may be beneficial to limit a project to C:

  • faster compilation because the language is much simpler
  • requires less runtime support, making it more suitable low-level environments
  • much easier to interface with other languages
  • supports variable sized arrays on the stack
  • easier to read assembly code because there is no name mangling
  • allows code produced by different compilers to be easily combined since it is the de facto standard application binary interface
dsh
  • 31
  • 1
  • 5
1

Portability may be an issue. Different to Gordon Carpenter-Thomp's answer, I would suggest that it's rather the runtime support of different versions of libstdc++ on different linux/unix versions. See this link for a good discussion about this. A little excerpt:

The runtime support code used by different parts of a C++ application needs to be compatible. If one part of the program needs to dynamic_cast or catch objects provided by another, both parts must agree on certain implementation details: how to find vtables, how to unwind the stack, and so on.

For C++ and a few other GCC-supported languages with similar features, such details are specified by a C++ ABI. Whenever the ABI used by GCC changes you'll end up with incompatible libraries produced by the different GCC versions. The same is true for plain C, but the C ABI is much simpler and has been around a lot longer so it's fairly stable.

Community
  • 1
  • 1
ferdystschenko
  • 1,527
  • 1
  • 9
  • 18
1

Most programmers take it for granted that everyone considers quality a high priority. That's not always the case. If you're use to C, C++ might seem like it's doing too much for you behind the scenes. The strictness of type checking in C++ might also seem confining. Many people are willing to risk introducing the kinds of bugs that C++ can help prevent to avoid these "nuisances."

  • 2
    Hmm, the reason I switched from C to C++ (a long time ago) was for the stricter type checking. I like having the compiler find my mistakes rather than the user experiencing a core dump. –  Mar 16 '09 at 11:20
0

There are various flavours of attempts of enhancing C into an object-oriented language: C++, C# and Objective-C. (Java and friends are just a flavour of C#, with even more problems)

C# implemented OO well and completely, but at the cost of the possibility of reverting to procedural design without introducing either hassle or code smell. Also, the introduction of a virtual machine made it difficult to write code that is anywhere near low level and it can never be self-hosted as the virtual machine itself have to be implemented in some language that can run natively. Java is even more problematic by making primitive types second-order citizen. (In C#, you have System.Int32 (a primitive type, int) : System.ValueType : System.Object, which makes primitive types still objects, but in Java primitive types are not objects at all). However, it is the most portable as compiled binaries that runs under virtual machines are inherently binary compatible under different platforms.

C++ did not use any virtual machine, and retained the C pointers, which make it still suitable for system development. (The kernel of OS X, Darwin, is largely written in C++, but a tight subset of which that does not have templates, multiple inheritance or STL, essentially a C++-looking dialect of Objective-C. Look at OS X IOKit documentation and you will find out) However C++ did not resolve those classical C issues at all while introducing more issues, including portability issues which is clearly the most obvious.

Objective-C went half ways in the middle of C++ and C#, as it is a simple mix of C (any version) and a modified Smalltalk dialect. Smalltalk, just like C#, treats everything as objects. It does not use a virtual machine as well, and it can still (requires!) use pointers, thus it can still be used as a system development language. (Weird why there is nobody doing it? I want to fork Minix and try implement a kernel with minimal assembler and C, and mostly Objective-C) With appropriate libraries Objective-C is largely code-compatible (that is, requires a recompile but no code change) between platforms just like C.

Maxthon Chan
  • 1,181
  • 8
  • 15
0
  • Because the compiler vendor only provides a C compiler which is certified for safety critical applications
  • Because the C++ FQA is scary. http://www.yosefk.com/c++fqa/
Sebastian
  • 1,839
  • 12
  • 16
0

Most people seem to think that C and C++ are somehow related, but they are sadly mistaken. C++ is a completely different language than C.

In C++, you think in terms of objects and how they are related to each other. In C, you think in terms of APIs. It's like the difference between day and 17.

A poor analogy: if someone adds Chinese to English and calls it English++, you probably wouldn't feel comfortable to add a Chinese line to your latest love letter, because it's so much easier to express love in this part of English++.

Philip
  • 5,795
  • 3
  • 33
  • 68
  • `C++` ***is not*** an OOP language. It's a multi-paradigm language. Thinking entirely in `objects` in `C++` will lead to awful, Java-like code. Besides, although ***most*** `C++` code in the real world shouldn't look like `C`, `C`-style code ***does*** have it's place in `C++`. `C++` is supposed to give its users full, `C`-style control of the program, including inline assembly. – Elliott Jul 10 '21 at 04:27