What would be C++ limitations compared C language? [closed]

Solution 1:

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.

Solution 2:

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.

Solution 3:

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?

Solution 4:

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.

Solution 5:

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.