Say an OS/kernel is written with C++ in mind and does not "do" any pure C style stuff, but instead exposes the C standard library built upon a full-fledged C++ standard library. Is this possible? If not, why?
PS: I know the C library is "part of C++", but let's say it's internally based on a C++-based implementation.
Small update: It seems I've stirred up a discussion as to what is "allowed" by my rules here. Generally speaking: the C Standard library implementation should use C++ everwhere that is possible/Right (tm). I mostly think about algorithms and acting on static class objects behind the scenes. I'm not really excluding any language features, but instead trying to put the emphasis on a sane C++ implementation. With regards to the setjmp example, I see no reason why valid C (which would use either other pre-implemented in C++ C library parts or not use any other library functions at all) here would be violation of my "rules". If there is no counterpart in the C++ library, why debate the use of it.
Yes, that is possible. It would be much like one exports a C API from a library written in C++, FORTRAN, assembler or most any other language for that matter.
Actually, c++ has the ability to be faster than c in many ways, due to it's ability to support many translationtime constructs like expression templates. For this reason, c++ matrix libraries tend to be much more optimised than c, involve less temporaries, unroll loops, etc. With new c++0x features like variant templates, the printf function, for instance, could be much faster and typesafe than a version implemented in c. It my even be able to honor the interfaces of many c constructs and evaluate some of their arguments (like string literals) translationtime.
Unfortunately, many people think c is faster than c++ because many people use OOP to mean that all relations and usage must occur through large inheritance hierarchies, virtual dispatch, etc. That caused some early comparisons to be completely different from what is considered good usage these days. If you were to use virtual dispatch where it is appropriate (e.g. like filesystems in the kernel, where they build vtables through function pointers and often basically build c++ in c), you would have no pessimisation from c, and with all of the new features, can be significantly faster.
Not only is speed a possible improvement, but there are places where the implementation would benefit from better type safety. There are common tricks in c (like storing data in void pointers when it must be generic) that break type safety and where c++ can provide strong error checking. This won't always translate through the interfaces to the c library, since those have fixed typing, but it will definitely be of use to the implementers of the library and could assist in some places where it may be possible to extract more information from calls by providing "as-if" interfaces (for instance, an interface that takes a void* might be implemented as a generic interface with a concept check that the argument is implicitly convertible to void*).
I think this would be a great test of the power of c++ over c.
Given that "pure C stuff" has such a large overlap with C++, I fail to see how you'd avoid it entirely in anything, much less an OS kernel. After all, is the + operation "pure C stuff"? :)
That said, you could certainly implement certain C library functions using classes and whatnot. Implement qsort using std::sort? Sure, no problem. Just don't forget your extern "C".
I see no reason why you couldn't do it, but I also see no reason why someone would use such an implementation. It's going to use a lot more memory, and be at least somewhat slower, than a normal implementation...although it might not be much worse than glibc, whose implementation of stdio is already essentially C++ anyway... (Lookup GNU libio... you'll be horrified.)
Kernels like Linux have very strict ABI, based on syscalls, ioctls, filesystems, and conforming to quite a few standards (POSIX being the major one). Since the ABI has to be stable its surface is also limited. It would be a lot of work (particularly since you need a minimally useful kernel as well), but these standards could be implemented in any language.
Edit: You mentioned the libc as well. That is not part of the kernel, and the language of the libc can be entirely unrelated to that of the kernel, thanks to the aforementioned ABI. Unlike the kernel, the libc needs to be C or have a very good ffi for C. C++ with parts in extern C would fit the bill.
Related
While developing a new product, we decided to go for a mix of C++ and C#, haven been told that bridging them to allow the C# code to call the C++ code would be easy (spoiler, it's not).
We're pretty experienced C++ programmers and not at all C# programmers so we pretty much just had to believe what we've read. A few attempts to call C and Objective-C was promising and we even found a few articles that showed how to make an unmanaged C++ class available in C# -- or at least we thought. The C++ code in the articles, wasn't C++, but instead the horrible monster C++/CLI that Microsoft seems to think is C++. Since we're doing the C# stuff to get some bits "for free" in macOS and Windows, C++/CLI isn't an option either :-(.
Anyway, plenty of people have claimed that it's easy to call C++ code from some specific programming language, but so far, I haven't seen a single one that will allow me to do so (I haven't been paying too much attention to this, so please provide me with an obvious example). C++ invariably always means C with no C++ stuff at all; no namespaces, classes, no stl, lambdas or anything. Just plain dumb C.
So, are there any languages, besides C++(/CLI) that will allow me to do the following:
Create an instance of a class, using a C++ constructor, and dispatch it with a C++ destructor.
Call member functions on an object ( foo f; f.foo();) with a C++ class.
Use std::vector, std::find_if, std::string and other stuff from the stl. Complete coverage of the stl is not required.
Use overloaded functions (i.e. f(), f(int), f(std::string))
Use overloaded operators (foo operator + (foo, foo))
Use C++11, C++14 and/or C++17 features.
Use RAII (rather important IMHO).
Use namespaces.
No. There is no such language.
Unless you count Objective-C++. But that falls pretty much in the same bucket as C++/CLI, in being C++ with some extensions. And C++/CX is another such beast.
There are some interop tools that can work with C++ classes (SWIG for example), but I have never heard of a tool that is capable of instantiating C++ templates (like vector or find_if) on demand.
What languages will call C++ with no explicit bridging?
The short answer to this question is: NONE
Remember that a programming language is a specification written in some technical report, usually in English. For examples, read n1570 (the spec of C11) or R5RS (the spec of Scheme). For C++, see n3337.
Actually, you are interested in implementations, e.g. in compilers and interpreters for your programming languages. These implementations are practically software. And then the answer might become: it depends (notably on the ABI used & targetted by your compiler and system).
See for examples this list of ABIs for Linux.
plenty of people have claimed that it's easy to call C++ code from some specific programming language,
The C calling conventions are quite common, and it might help to declare every C++ function callable from outside as extern "C". But there is no silver bullet, and details matter a lot.
So, are there any languages, besides C++(/CLI) that will allow me to do the following:
list of C++ features skipped
Probably not.
You probably need at least to understand more about memory management approaches. I recommend understanding more about garbage collection, e.g. by reading the GC handbook (at least for underlying concepts & terminology). Learn more about foreign function interfaces (in some cases, the libffi might help) and language bindings.
You might also consider generating some of the C++ or C glue code, maybe with SWIG (or write your own C++ glue code generator).
On operating systems providing dynamic linking capable of loading plugins at runtime (e.g. Linux with dlopen(3)/dlsym(3); but other OSes often have similar facilities) you could even consider generating some C or C++ glue code at runtime in some temporary file, compile it as a temporary plugin, and dynamically loading that plugin. You could also consider JIT-compiling libraries like GCCJIT or LLVM (or libjit).
I recommend reading SICP, the Dragon Book, and probably Lisp In Small Pieces. Of course, learn something about OSes, e.g. Operating Systems: Three Easy Pieces. Reading about Linkers and Loaders could also help.
As an excellent example of cleverly gluing C++, look into CLASP and see this video.
But whatever approach you take, you'll need a lot of work (years, not weeks).
C++ as a language does not have a defined ABI (Application Binary Interface) - which basically means that there is no universal standard of what a C++ class/function call/template would look like in binary form on any given platform, or across platforms.
What that means is that there is no universal way to call C++ code from other languages, on different platforms, or even across compilers on the same platform. It also means that the people who are telling you "it's easy to call C++ code from XYZ language" are mostly incorrect (or at least incredibly incomplete).
Where there are interfaces it's either because the provider of the interface controls the ABI (C++/CLI with .NET), or because there is a translation layer from C++ to something like the C calling convention (Boost::python).
Some work has been done towards attempting to define an ABI per-platform (http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4028.pdf), but as far as I'm aware it has not yet been accepted into C++17.
You can look into using C++ interpreter, which allows for the fine-grained control you ask for. But I don't know of any that "just works", see also:
Have you used any of the C++ interpreters (not compilers)?
I saw this link but I'm not asking for a performance degradation for code using "extern". I mean without "extern", is there "context switching" when using C library in C++?
Are there any problems when using pure C (not class-wrapped) functions in C++ application?
Both C and C++ are programming language specifications (written in English, see e.g. n1570 for the specification of C11) and do not speak about performance (but about behavior of the program, i.e. about semantics).
However, you are likely to use a compiler such as GCC or Clang which don't bring any performance penalty, because it builds the same kind of intermediate internal representation (e.g. GIMPLE for GCC, and LLVM for Clang) for both C and C++ languages, and because C and C++ code use compatible ABIs and calling conventions.
In practice extern "C" don't change any calling convention but disables name mangling. However, its exact influence on the compiler is specific to that compiler. It might (or not) disable inlining (but consider -flto for link-time-optimization in GCC).
Some C compilers (e.g. tinycc) produce code with poor performance. Even GCC or Clang, when used with -O0 or without explicitly enabling optimization (e.g. by passing -O1 or -O2 etc...) might produce slow code (and optimizations are by default disabled with it).
BTW, C++ was designed to be interoperable with C (and that strong constraint explains most of the deficiencies of C++).
In some cases, genuine C++ code might be slightly faster than corresponding genuine C code. For example, to sort an array of numbers, you'll use std::array and std::sort in genuine C++, and the compare operations in the sort are likely to get inlined. With C code, you'll just use qsort and each compare goes through an indirect function call (because the compiler is not inlining qsort, even if in theory it could...).
In some other cases, genuine C++ code might be slightly slower; for example, several (but not all) implementations of ::operator new are simply calling malloc (then checking against failure) but are not inlined.
In practice, there is no penalty in calling C code from C++ code, or C++ code from C code, since the calling conventions are compatible.
The C longjmp facility is probably faster than throwing C++ exceptions, but they don't have the same semantics (see stack unwinding) and longjmp doesn't mix well accross C++ code.
If you care that much about performance, write (in genuine C and in genuine C++) twice your code and benchmark. You are likely to observe a small change (a few percents at most) between C and C++, so I would not bother at all (and your performance concerns are practically unjustified).
Context switch is a concept related to operating system and multitasking and happens on processes running machine code executable during preemption. How that executable is obtained (from a C compiler, from a C++ compiler, from a Go compiler, from an SBCL compiler, or being an interpreter of some other language like Perl or bytecode Python) is totally irrelevant (since a context switch can happen at any machine instruction, during interrupts). Read some books like Operating Systems: Three Eeasy Pieces.
At a basic level, no, you won't see any type of "switching" performance penalty when calling a C library from C++ code. For example calling from C++ a C method defined in another translation unit should have approximately identical performance to calling the same method implemented in C++ (in the same C-like way) in another translation unit.
This is because common implementations of C and C++ compilers ultimately compile the source down to native code, and calling an extern "C" function is efficiently supported using the same type of call that might occur for a C++ call. The calling conventions are usually based on the platform ABI and are similar in either case.
That basic fact aside, there might still be some performance downsides when calling a C function as opposed to implementing the same function in C++:
Functions implemented in C and declared extern "C" and called from C++ code usually won't be inlined (since by definition they aren't implemented in a header), which inhibits a whole host of possibly very powerful optimization0.
Most data types used in C++ code1 can't be directly used by C code, so for example if you have a std::string in your C++ code, you'll need to pick a different type to pass it to C code - char * is common but loses information about the explicit length, which may be slower than a C++ solution. Many types have no direct C equivalent, so you may be stuck with a costly conversion.
C code uses malloc and free for dynamic memory management, while C++ code generally uses new and delete (and usually prefers to hide those calls behind other classes as much as possible). If you need to allocate memory in one language that will be freed in other other, this may cause a mismatch where you need to call back into the "other" language to do the free, or may unnecessary copies, etc.
C code often makes heavy use of the C standard library routines, while C++ code usually uses methods from the C++ standard library. Since there is a lot of functional overlap, it is possible that a mix of C and C++ has a larger code footprint than pure C++ code since more C library methods are used2.
The concerns above would apply only when contrasting a pure C++ implementation versus a C one, and doesn't really mean there is a performance degradation when calling C: it is really answering the question "Why could writing an application in a mix of C and C++ be slower than pure C++?". Furthermore, the above issues are mostly a concern for very short calls where the above overheads may be significant. If you are calling a lengthy function in C, it is less of a problem. The "data type mismatch" might still bite you, but this can be designed around on the C++ side.
0 Interestingly, link-time optimization actually allows C methods to be inlined in C++ code, which is a little-mentioned benefit of LTO. Of course, this is generally dependent on building the C library yourself from source with the appropriate LTO options.
1 E.g., pretty much anything other than a standard layout type.
2 This is at least partially mitigated by the fact that many C++ standard library calls ultimately delegate to C library routines for the "heavy" lifting, such as how std::copy calls memcpy or memset when possible and how most new implementations ultimately call malloc.
C++ has grown and changed a lot since its inception, but by design it is backwards-compatible with C. C++ compilers are generally built from C compilers, but even more modernized with link-time optimizations. I would imagine lots of software can reliably mix C and C++ code, both in the user spaces and in the libraries used. I answered a question recently that involved passing a C++ class member function pointer, to a C-implemented library function. The poster said it worked for him. So it's possible C++ is more compatible with C than any programmers or users would think.
However, C++ works in many different paradigms that C does not, as it is object-oriented, and implements a whole spectrum of abstractions, new data types, and operators. Certain data types are easily translatable (char * C string to a std::string), while others are not. This section on GNU.org about C++ compiler options may be of some interest.
I would not be too worried or concerned about any decline in performance, when mixing the two languages. The end user, and even the programmer, would hardly notice any measurable changes in performance, unless they were dealing with big abstractions of data.
Is it possible to write the complete C++ standard library (including STL of course, but self-contained, only internal dependencies) using only C++? I would imagine containers and <cstdlib> functionality would be doable in terms of chars, bitshifts, and for loops and other byte fancy things, but stuff like exceptions and perhaps std::cout and std::cin seem hard to me without a dependency to begin with. Let's say there is a set of OS functions available, that are completely implemented in assembly (to avoid any C contamination).
I'm assuming the compiler understands everything from classes and virtual functions to templates and function overloading, these are language level things and have no place in a library IMHO.
If this has been asked before or is a trivially stupid question, please forgive me. I'm not trying to start a C<->C++ war here, just trying to figure out the limitations of implementing a beast such as the Standard library...
Thanks!
Since pretty much anything written in C can be rewritten fairly easily in C++, you're asking whether assembly code is needed, and the answer is generally no.
Unless we're talking about embedded programming, operating systems have all the necessary file and I/O functionality available through system calls, usually (nowadays) in C format. The library needs to call them, likely through extern "C"{ ... } declarations. The operating system functions are not considered part of the C++ library, and typically aren't exact matches to anything defined in the C++ Standard.
To implement a C++ standard library, you would need to be familiar with the language itself, know the OS calls you're going to use, and have the algorithms you're going to use. At that point, it's a relatively straightforward matter of writing the software.
First thing, it doesn't matter if it's C, C++, or D. Any compilable programming language at the end gives you (mostly) the same assembly object file.
Second thing, STL is written in C++, you cannot write C++ library in C or any other language (well, you can but I assume, that we're talking on reasonable solutions). You cannot implement STL containers in C, because the're strongly use templates.
GCC generate really nice output in asm for exceptions now. I recommend to read about C++ ABI (if you're interested in it).
C++ compiler understands all C++ specific features really nice nowadays. Thanks to really advanced code analysis and optimizations, it's able to produce fast executables (see first paragraph).
I hope that I've at least partly answered your question.
The only piece of C++ that needs assembly is the exception handling. I suppose that it might be doable in C++ if there exist libraries to handle the necessary register and stack management.
Of course, those libraries would then include assembly. There just isn't any other way to do direct register management.
The STL is very heavily reliant on #includeed header files. Those pretty much have to be C++.
Anything that isn't in one of those header files though could in theory be implemented in C, Ada, Assembly, or the other systems-programming language of your choice. However, you'd probably have to be maintaining two interfaces if you don't make at least the top layer C++.
D easily interfaces with C.
D just as easily interfaces with C++, but (and it's a big but) the C++ needs to be extremely trivial. The code cannot use:
namespaces
templates
multiple inheritance
mix virtual with non-virtual methods
more?
I completely understand the inheritance restriction. The rest however, feel like artificial limitations. Now I don't want to be able to use std::vector<T> directly, but I would really like to be able to link with std::vector<int> as an externed template.
The C++ interfacing page has this particularly depressing comment.
D templates have little in common with
C++ templates, and it is very unlikely
that any sort of reasonable method
could be found to express C++
templates in a link-compatible way
with D.
This means that the C++ STL, and C++
Boost, likely will never be accessible
from D.
Admittedly I'll probably never need std::vector while coding in D, but I'd love to use QT or boost.
So what's the deal. Why is it so hard to express non-trivial C++ classes in D? Would it not be worth it to add some special annotations or something to express at least namespaces?
Update:
"D has namespace support in the works" from Walter Bright.
FWIW Qt has an actively developed binding for D: http://www.dsource.org/projects/qtd
I think many components in boost are too highly tied to C++ to be portable meaningfully to other languages.
Using e.g. std::vector is possible if you spend the time on writing regular (e.g. namespace-level) functions that forward to the appropriate member functions. Tedious, but affordable (for higher-level components; probably not for std::vector).
Also, I very recently checked in the standard library a sealed array and sealed binary heap implementation that use reference counting, malloc/free, and deterministic destruction instead of garbage collection (see http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/container.d). Other containers will follow. These containers use three specific techniques (described in my upcoming article "Sealed Containers") to achieve deterministic destruction without compromising program safety.
Hopefully sealed containers will obviate any need to link with STL containers, even for tight applications that can't afford garbage collection.
As Hans Passant mentions in a comment, the level of interoperability you want between D and C++ isn't even supported among different C++ compilers. There is a C++ ABI (Application Binary Interface) standard that seems to have some support, but I'm not sure exactly how extensive (Intel, GCC and ARM compilers seem to follow the ABIs). I haven't had a need to use it, and I'm not sure whether or not Microsoft adheres to it for their x86 or x64 compilers (I imagine it might for ia64, since that's where the ABI standard started).
See "Interoperability & C++ Compilers" by Joe Goodman for some details on the C++ ABI.
Maybe Walter Bright can be convinced to support D interoperability with C++ libraries/objects that follow the ABI standard (though I'm not sure where he might prioritize it).
Just for fun I've been interfacing to some C++ code.
That probably won't answer for your question, but I think you (and some folks among the D community) might be interested in some notes I've made then. Here it goes: TechNotes.
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 )