What Would Be C++ Limitations Compared C Language

What would be C++ limitations compared C language?

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.

C vs C++ - advantages with c-language

In simple, C and C++ are two different languages.

C++, as the name suggests, is a superset of C

No. This is not true. C++ is not a superset of C..

Is there ANY advantage with c-language compared with c++? Is there anything whatsoever that is better with c than with c++?

  • Static initialize is safe in C but not in C++, because in C++ static initialization can cause code to run, which depends on other variables having been statically initialized. It can also cause cleanup code to run at shutdown which you can't control sequence of (destructors).

  • C gives you better control over what happens when your code is executed. When reading seek out it is fairly straightforward to decipher one code is getting executed and when memory is just restart or primitive operations are performed.

  • C supports variable sized arrays on the stack. Which is much faster to allocate than on the heap. (C99 feature)

  • No name mangling. If you intend to read generated assembly code, this makes that much easier. It can be useful when trying to optimize code.
    De facto standard application binary interface (ABI). Code produced by different compilers can easily be combined.

  • Much easier to interface with other languages. A lot of languages will let you call C functions directly. Binding to a C++ library is usually a much more elaborate job.

  • Compiling C programs is faster than compiling C++ programs, because parsing C is much easier than parsing C++.

  • Varargs cannot safely be used in C++. They're not entirely safe in in C either. However they're much more so in the C++, to the point that they are prohibited in the C++ coding standards (Sutter, Alexandrescu).

  • C requires less runtime support. Makes it more suitable for low-level environments such as embedded systems or OS components.

  • Standard way in C to do encapsulation is to forward declare a struct and only allow access to its data through functions. This method also creates compile time encapsulation. Compile time encapsulation allows us to change the data structures members without recompilation of client code (other code using our interface). The standard way of doing encapsulation C++ on the other hand (using classes) requires recompilation of client code when adding or removing private member variables.

Has the use of C to implement other languages constrained their designs in any way?

Even with a C implementation, you're surprisingly free in terms of implementation. For example, chicken scheme uses C as an intermediate, but still manages to use the stack as a nursery generation in its garbage collector.

That said, there are some cases where there are constraints. Case in point: The GHC haskell compiler has a perl script called the Evil Mangler to alter the GCC-outputted assembly code to implement some important optimizations. They've been moving to internally-generated assembly and LLVM partially for that reason. That said, this hasn't constrained the language design - only the compiler's choice of available optimizations.

Why do people still use C when they have C++?

C is much simpler, and more fun to program in.

But what's more, the compiler is much much easier to write so there are still lots of environments where you can either only get a C compiler or the C++ compiler is far inferior (buggy, slower, generates bloated binaries).

Is C inefficient compared to Assembly?

Modern C can do a better job than assembly in many cases, because keeping track of which operations can overlap and which will block others is so complex it can only be reasonably be tracked by a computer.

What if any, programming fundamentals are better learned in C as opposed to C++?

If all you've ever used is object-oriented programming languages like C++ then it would be worthwhile to practice a little C. I find that many OO programmers tend to use objects like a crutch and don't know what to do once you take them away. C will give you the clarity to understand why OO programming emerged in the first place and help you to understand when its useful versus when its just overkill.

In the same vein, you'll learn what it's like to not rely on libraries to do things for you. By noting what features C++ developers turned into libraries, you get a better sense of how to abstract your own code when the time comes. It would be bad to just feel like you need to abstract everything in every situation.

That said, you don't have to learn C. If you know C++ you can drag yourself through most projects. However, by looking at the lower-level languages, you will improve your programming style, even in the higher-level ones.

Using Go in C limitations

In theory, there are no limitations - conceptually the .so is just a bunch of machine code that happens to bundle a very smart memory manager, and expose an API that matches the shared library format.

There are, in practice, a minimal set of quirks. For instance, the program linking in the go .so can currently not call dlclose on it: https://github.com/golang/go/issues/11100

You may find the open list of issues mentioning c-shared to be helpful: https://github.com/golang/go/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20c-shared

Comparative advantages between C vs C++ for new projects

C++ simply has many more features than C. That makes it a more complex language. But the benefit of using these features is that you will have to write (and maintian) less code.

You're not required to use templates, stl, exceptions, function overloads, or whatever C++ feature. But if your problem needs just one of these features, your program will be more readable if you do it in C++, rather than emulating the missing functionality in C.

Is it true that there is no need to learn C because C++ contains everything?

Overview:

It is almost true that C++ is a superset of C, and your professor is correct in that there is no need to learn C separately.

C++ adds the whole object oriented aspect, generic programming aspect, as well as having less strict rules (like variables needing to be declared at the top of each function). C++ does change the definition of some terms in C such as structs, although still in a superset way.

Examples of why it is not a strict superset:

This Wikipedia article has a couple good examples of such a differences:

One commonly encountered difference is
that C allows implicit conversion from
void* to other pointer types, but C++
does not. So, the following is valid C
code:

int *i = malloc(sizeof(int) * 5);  

... but to make it work in both C and
C++ one would need to use an explicit
cast:

int *i = (int *) malloc(sizeof(int) * 5)

Another common portability issue is
that C++ defines many new keywords,
such as new and class, that may be
used as identifiers (e.g. variable
names) in a C program.

This wikipedia article has further differences as well:

C++ compilers prohibit goto from crossing an initialization, as in the following C99 code:

 void fn(void)
{
goto flack;
int i = 1;
flack:
;
}

What should you learn first?

You should learn C++ first, not because learning C first will hurt you, not because you will have to unlearn anything (you won't), but because there is no benefit in learning C first. You will eventually learn just about everything about C anyway because it is more or less contained in C++.



Related Topics



Leave a reply



Submit