Compiler memory consumption with template libraries (boost + Eigen) - c++

I am writing a template algorithm that makes use of boost::accumulators and the Eigen linear algebra library.
While compiling, the visual studio compiler (cl.exe), memory consumption peaks at over 2.5GB of RAM, and my PC (windows 7 32 bit with 3GB virtual address space) becomes unresponsive (for quite a long time: ~1 minute). The binary files (.obj) are 10-20MB for these compilation units.
My questions (not directed towards these specific libraries)
Is this normal behavior for code that heavily uses templates?
Is there something that can be done to reduce the memory demands and
compile time?
If there is no good solution to the problem, why isn't this
addressed by the people that design the programming language? The
more people understand C++, the more they are likely to use templates, and generate hard-to compile code, and bloated binaries.

If there is no good solution to the problem, why isn't this addressed
by the people that design the programming language?
Because there is no good solution, full stop.
The problem you are talking about has nothing to do with C++. It's an artefact from C- the old "translation unit". Fixing this problem would require re-doing the compilation model. The C++ Committee has been trying for years to make this happen without breaking every single line of existing C++ out there (which is a bigger consideration), but it's not a trivial problem. Fixing it would require vast changes.
Also, Clang has way better performance, and newer versions of GCC which are variadic-template-equipped can do as well.

Yes. Compiling templates is memory consuming. Some implementations suck more than others. In my personal experience, out of GCC, MSVC and Clang, the latter is the best at managing its memory use.
You can split your huge source files into several smaller ones. That would even out the load over several compile steps.
The people who designed the programming language only cared very little for the implementation, to give compiler writers enough freedom to excel and compete. Or Suck.

Related

JIT compilation of C++ templates at compile time

Would JIT-compiling a C++ template at compile time be a viable strategy for faster compile times? Is this maybe already done in large compilers like LLVM, and if not, what are the (maybe obvious) downsides making this non-viable?
For clarification, what I mean is that one takes the C++ template language, not as an interpreted system for generating C++ AST, but as a JIT-compilable language that one passes to e.g. LLVMJit or similar systems that emit binary blobs that in-turn generate the resulting AST of the template application result, given the template arguments.
Would this theoretically speed up some compilation times? AFAIK, JIT/interpretation speedup depends heavily on the frequency of the called code, but I can imagine some templates as being applied many times.
Would JIT-compiling a C++ template at compile time be a viable strategy for faster compile times?
Certainly yes, but implementing that idea will take you several years of work full-time. Consider making your PhD thesis on that topic (the issue is to find a good PhD advisor).
In practice, every modern C++ compiler (e.g. GCC or Clang/LLVM) evolved from a simpler C (or old C++) compiler.
Another (perhaps related) research topic is to make a C++ compiler with both JIT-compiling techniques and multi-threading.
Both GCC or Clang/LLVM are (in end of 2021) monothreaded compilers. You might consider adding several pthreads inside them.
The issue is to find a good qualified PhD advisor. I am not qualified enough for that role.
A related book is of course: Pitrat's book (yellow cover) on Artificial Beings, the conscience of a conscious machine
On Linux, a possibility could be to generate GCC plugins tailored in compiling a known set of C++ templates, and dlopen-ed at compile time. My old Bismon could be a starting point. Or the RefPerSys project....

why my visual studio 2013 is slow for c++ code compiling

a c++ project, even if I only change minor code, it will spend a lot on time for compiling like below
and I found when I compile, the cl. exe must load a huge of memory by several MB's speed, anyone have idea for this situation
anyway , the code's result is correct but every time a lot of time is wasted on compiling , hope some one could help me
That's actually not a lot of memory.
Modern C++ compilers assume that developers have decent PC's. Unlike JIT compilers (as in Java JVM's), normal C++ compilers have a very strong bias towards better code generation at the expense of compile-time efficiency.
This is also driven by the fact that PC's are generally a lot cheaper than developers. 8-16 GB of memory is not excessively expensive.

Developing embedded software library, C or C++?

I'm in the process of developing a software library to be used for embedded systems like an ARM chip or a TI DSP (for mostly embedded systems, but it would also be nice if it could also be used in a PC environment). Obviously this is a pretty broad range of target systems, so being able to easily port to different systems is a priority.The library will be used for interfacing with a specific hardware and running some algorithms.
I am thinking C++ is the best option, over C, because it is much easier to maintain and read. I think the additional overhead is worth it for being able to work in the object oriented paradigm. If I was writing for a very specific system, I would work in C but this is not the case.
I'm assuming that these days most compilers for popular embedded systems can handle C++. Is this correct?
Is there any other factors I should consider? Is my line of thinking correct?
If portability is very important for you, especially on an embedded system, then C is certainly a better option than C++. While C++ compilers on embedded platforms are catching up, there's simply no match for the widespread use of C, for which any self-respecting platform has a compliant compiler.
Moreover, I don't think C is inferior to C++ where it comes to interfacing hardware. The amount of abstraction is sufficiently low (i.e. no deep class hierarchies) to make C just as good an option.
There is certainly good support of C++ for ARM. ARM have their own compiler and g++ can also generate EABI compliant ARM code. When it comes to the DSPs, you will have to look at their toolchain to decide what you are going to do. Be aware that the library that comes with a DSP may well not implement the full C or C++ standard library.
C++ is suitable for low-level embedded development and is used in the SymbianOS Kernel. Having said that, you should keep things as simple as possible.
Avoid exceptions which may demand more library support than what is present (therefore use new (std::nothrow) Foo instead of new Foo).
Avoid memory allocations as much as possible and do them as early as possible.
Avoid complex patterns.
Be aware that templates can bloat your code.
I have seen many complaints that C++ is "bloated" and inappropriate for embedded systems.
However, in an interview with Stroustrup and Sutter, Bjarne Stroustrup mentioned that he'd seen heavily templated C++ code going into (IIRC) the braking systems of BMWs, as well as in missile guidance systems for fighter aircraft.
What I take away from this is that experts of the language can generate sophisticated, efficient code in C++ that is most certainly suitable for embedded systems. However, a "C With Classes"[1] programmer that does not know the language inside out will generate bloated code that is inappropriate.
The question boils down to, as always: in which language can your team deliver the best product?
[1] I know that sounds somewhat derogatory, but let me say that I know an awful lot of these guys, and they churn out an awful lot of relatively simple code that gets the job done.
C++ compilers for embedded platforms are much closer to 83's C with classes than 98's C++ standard, let alone C++0x. For instance, some platform we use still compile with a special version of gcc made from gcc-2.95!
This means that your library interface will not be able to provide interfaces with containers/iterators, streams, or such advanced C++ features. You'll have to stick with simple C++ classes, that can very easily be expressed as a C interface with a pointer to a structure as first parameter.
This also means that within your library, you won't be able to use templates to their full power. If you want portability, you will still be restricted to generic containers use of templates, which is, I'm sure you'll admit, only a very tiny part of C++ templates power.
C++ has little or no overhead compared to C if used properly in an embedded environment. C++ has many advantages for information hiding, OO, etc. If your embedded processor is supported by gcc in C then chances are it will also be supported with C++.
On the PC, C++ isn't a problem at all -- high quality compilers are extremely widespread and almost every C compiler is directly associated with a C++ compiler that's quite good, though there are a few exceptions such as lcc and the newly revived pcc.
Larger embedded systems like those based on the ARM are generally quite similar to desktop systems in terms of tool chain availability. In fact, many of the same tools available for desktop machines can also generate code to run on ARM-based machines (e.g., lots of them use ports of gcc/g++). There's less variety for TI DSPs (and a greater emphasis on quality of generated code than source code features), but there are still at least a couple of respectable C++ compilers available.
If you want to work with smaller embedded systems, the situation changes in a hurry. If you want to be able to target something like a PIC or an AVR, C++ isn't really much of an option. In theory, you could get (for example) Comeau to produce a custom port that generated code you could compile on that target's C compiler -- but chances are pretty good that even if you did, it wouldn't work out very well. These systems are really just too limitated (especially on memory size) for C++ to fit them well.
Depending on what your intended use is for the library, I think I'd suggest implementing it first as C - but the design should keep in mind how it would be incorporated into a C++ design. Then implement C++ classes on top of and/or along side of the C implementation (there's no reason this step cannot be done concurrently with the first). If your C design is done with a C++ design in mind, it's likely to be as clean, readable and maintainable as the C++ design would be. This is somewhat more work, but I think you'll end up with a library that's useful in more situations.
While you'll find C++ used more and more on various embedded projects, there are still many that restrict themselves to C (and I'd guess this is more often the case than not) - regardless of whether or not the tools support C++. It would be a shame to have a nice library of routines that you could bring to a new project you're working on, but be unable to use them because C++ isn't being used on that particular project.
In general, it's much easier to use a well-designed C library from C++ than the other way around. I've taken this approach with several sets of code including parsing Intel Hex files, a simple command parser, manipulating synchronization objects, FSM frameworks, etc. I'm planning on doing a simple XML parser at some point.
Here's an entirely different C++-vs-C argument: stable ABIs. If your library exports a C ABI, it can be compiled with any compiler that works on the system, because C ABIs are generally platform standards. If your library exports a C++ ABI, it can only be compiled with a matching compiler -- because C++ ABIs are usually not platform standards, and often differ from compiler to compiler and even version to version.
Interestingly, one of the rare exceptions to this is ARM; there's an ARM C++ ABI specification, and all compliant ARM compilers follow it. This is not true on x86; on x86, you're lucky if a C++ library compiled with a 4.1 version of GCC will link correctly with an application compiled with GCC 4.4, and don't even ask about 3.4.6.
Even if you export a C ABI, you can have problems. If your library uses C++ internally, it will then link to libstdc++ for things in the C++ std:: namespace. If your user compiles a C++ application that uses your library, they'll also link to libstdc++ -- and so the overall application gets linked to libstdc++ twice, and their libstdc++ may not be compatible with your libstdc++, which can (or so I understand) lead to odd errors from the intersection of the two. Considerably less likely, but still possible.
All of these arguments only apply because you're writing a library, and they're not showstoppers. But they are things to be aware of.

Why is it important for C / C++ Code to be compilable on different compilers?

I'm
interested in different aspects of portability (as you can see when browsing my other questions), so I read a lot about it. Quite often, I read/hear that Code should be written in a way that makes it compilable on different compilers.
Without any real life experience with gcc / g++, it seems to me that it supports every major platform one can imagine, so Code that compiles on g++ can run on almost any system. So why would someone bother to have his code run on the MS Compiler, the Intel compiler and others?
I can think of some reasons, too. As the FAQ suggest, I'll try to post them as an answer, opposed to including them into my own question.
Edit: Conclusion
You people got me completely convinced that there are several good reasons to support multiple compilers. There are so many reasons that it was hard to choose an answer to be the accepted one. The most important reasons for me:
Contributors are much more likely to work an my project or just use it if they can use the compiler of their choice
Being compilable everywhere, being usable with future compilers and tools, and adhering to the standards are enforcing each other, so it's a good idea
On the other hand, I still believe that there are other things which are more important, and now I know that sometimes it isn't important at all.
And last of all, there was no single answer that could convince me not to choose GCC as the primary or default compiler for my project.
Some reasons from the top of my head:
1) To avoid being locked with a single compiler vendor (open source or not).
2) Compiling code with different compilers is likely to discover more errors: warnings are different and different compilers support the Standard to a different degree.
It is good to be compilable on MSVC, because some people may have projects that they build in MSVC that they want to link your code into, without having to set up an entirely different build system.
It is good to be compilable under the Intel compiler, because it frequently compiles faster code.
It is good to be compilable under Clang, because it can give better error messages and provide a better development experience, and it is an easier project to work on than GCC and so may gain additional benefits in the future.
In general, it is good to keep your options open, because there is no one compiler that fits all needs. GCC is a good compiler, and is great for most purposes, but you sometimes need something else.
And even if you're usually only going to be compiling under GCC, making sure your code compiles under other compilers is also likely to help find problems that could prevent your code from working with past and future versions of GCC, for instance, if there's something that GCC is less strict about now, but later adds checks for, another compiler may catch in advance, helping you keep your code cleaner. I've found this helpful in the reverse case, where GCC caught more potential problems with warnings than MSVC did (MSVC is the only compiler we needed to support, as we were only shipping on Windows, but we did a partial port to the Mac under GCC in our free time), which allowed me to produce cleaner code than I would have otherwise.
Portability. If you want your code to be accessible by the maximum number of people possible, you have to make it work on the widest range of possible compilers. It the same idea as make a web site run on browsers other than IE.
Some of it is political. Companies have standards, people have favorite tools etc. Telling someone that they should use X, really puts some people off, and makes it really inaccessible to others.
Nemanja brings up a good point too, targeting for a certain compiler locks you into to using it. In the Open Source world, this might not be as big of a problem (although people could just stop developing on it and it becomes obsolete), but what if the company you buy it from discontinues the product, or goes out of business?
For most languages I care less about portability and more about conforming to international standards or accepted language definitions, from which properties portability is likely to follow. For C, however, portability is a useful idea, because it is very hard to write a program that is "strictly conforming" to the standard. (Why? Because the standards committees felt it necessary to grandfather some existing practice, including giving compilers some freedom you might not like them to have.)
So why try to conform to a standard or make your code acceptable to multiple compilers as opposed to simply writing whatever gcc (or your other favorite compiler) happens to accept?
Likely in 2015 gcc will accept a rather different language than it does today. You would prefer not to have to rewrite your old code.
Perhaps your code might be ported to very small devices, where the GNU toolchain is not as well supported.
If your code compiles with any ANSI C compiler straight out of the box with no errors and no warnings, your users' lives will be easier and your software may be widely ported and used.
Perhaps someone will invent a great new tool for analyzing C programs, refactoring C programs, improving performance of C programs, or finding bugs in C programs. We're not sure what version of C that tool will work on or what compiler it might be based on, but almost certainly the tool will accept standard C.
Of all these arguments, it's the tool argument I find most convincing. People forget that there are other things one can do with source code besides just compile it and run it. In another language, Haskell, tools for analysis and refactoring lagged far behind compilers, but people who stuck with the Haskell 98 standard have access to a lot more tools. A similar situation is likely for C: if I am going to go to the effort of building a tool, I'm going to base it on a standard with a lifetime of 10 years or so, not on a gcc version which might change before my tool is finished.
That said, lots of people can afford to ignore portability completely. For example, in 1995 I tried hard to persuade Linus Torvalds to make it possible to compile Linux with any ANSI C compiler, not just gcc. Linus had no interest whatever—I suspect he concluded that there was nothing in it for him or his project. And he was right. Having Linux compile only with gcc was a big loss for compiler researchers, but no loss for Linux. The "tool argument" didn't hold for Linux, because Linux became so wildly popular; people building analysis and bug-finding tools for C programs were willing to work with gcc because operating on Linux would allow their work to have a big impact. So if you can count on your project becoming a wild success like Linux or Mosaic/Netscape, you can afford to ignore standards :-)
If you are building for different platforms, you will end up using different compilers. Moreover, C++ compilers tend to be always slightly behind the C++ standard, which means they usually change their adherence to it as time passes. If you target the common denominator to all major compilers then the code maintenance cost will be lower.
It's very common for applications (especially open-source application) that other developers would desire to use different compilers. Some would rather be using Visual Studio with MS Compiler for development purposes. Some would rather use Intel compiler for claimed performance benefits and such.
So here are the reasons I can think of
if speed is the biggest concern and there is special, highly optimized compiler for some platforms
if you build a library with a C++ interface (classes and templates, instead of just functions). Because of name mangling and other stuff, the library must be compiled with the same compiler as the client code, and if the client wants to use Visual C++, he must be able to compile the lib with it
if you want to support some very rare platform that does not have gcc support
(For me, those reasons are not significant, since I want to build a library that uses C++ internally, but has a C interface.)
Typically these are the reasons that I've found:
cross-platform (windows, linux, mac)
different developers doing development on different OS's (while not optimal, it does happen - testing usually takes place on the target platform only).
Compiler companies go out of business - or stop development on that language. If you know your program compiles/runs well using another compiler, you've covered your bet.
I'm sure there are other answers as well, but these are the most common reasons I've run into so far.
Several projects use GCC/G++ as a "day-to-day" compiler for normal use, but every so often will check to make sure their code follows the standards with the Comeau C/C++ compiler. Their website looks like a nightmare, and the compiler isn't free, but it's known as possibly the most standards-compliant compiler around, and will warn you about things many compilers will silently accept or explicitly allow as a nonstandard extension (yes, I'm looking at you, Mr. I-don't-mind-and-actually-actively-support-your-efforts-to-do-pointer-arithmetic-on-void-pointers-GCC).
Compiling every so often with a compiler as strict as Comeau (or, even better, compiling with as many compilers as you can get your hands on) will let you know of errors people might experience when trying to compile your code, things your compiler allows you to do that it shouldn't, and potentially things that other compilers don't allow you to do that you should. Writing ANSI C or C++ should be an important goal for code you intend to use on multiple platforms, and using the most standards-compliant compiler around is a good way to do that.
(Disclaimer: I don't have Comeau, and don't plan on getting it, and can't get it because I'm on OS X. I do C, not C++, so I can actually know the whole language, and the average C compiler is much closer to the C standard than the average C++ compiler to the C++ standard, so it's less of an issue for me. Just wanted to put this in here because this started to look like an ad for Comeau. It should be seen more as an ad for compiling with many different compilers.)
This one of those "It depends" questions. For open source code, it's good to be portable to multiple compilers. After all having people in diverse environments build the code is sort of the point.
But for closed source, This is a lot less important. You never want to unnecessarily tie yourself to a specific compiler. But in most of the places I've worked, compiler portability didn't even make into the top 10 of things we cared about. Even if you never use anything other than standerd C/C++, switching a large code base to a new compiler is a dangerous thing to do. Compilers have bugs. Sometimes your code will have bugs that are benign on one compiler, but suddenly a problem on another.
I remember one transition, where one compiler thought this code was just fine:
for (int ii = 0; ii < n; ++ii) { /* some code */ }
for (int ii = 0; ii < y; ++ii) { /* some other code */ }
While the newer compiler complained that ii had been declared twice, so we had to go through all of our code and declare loop variables before the loop in order to switch.
One place I worked was so careful about unintended side effects of compiler switches, that they checked specific compilers into each source tree, and once the code shipped would only use that one compiler to do updates on that code base - forever.
Another place would try out a new compiler for 6 months to a year before they switched over to it.
I find gcc a slow compiler on windows (nothing to compare against under linux). So I (sometimes) want to compile my code under other compilers, just for faster development cycles.
I don't think anyone has mentioned it so far, but another reason may be access to certain platform-specific features: Many operating system vendors have special versions of GCC, or even their own home-grown (or licensed and modified) compilers. So if you want your code to run well on several platforms, you may need to choose the right compiler on each platform. Be that an embedded system, MacOS, Windows etc.
Also, speed may be an issue (both compilation speed and execution speed). Back in the PPC days, GCC produced notoriously slow code on PowerPC CPUs, so Apple put a bunch of engineers on GCC to improve that (GCC was very new for the Mac, and all other PowerPC platforms were small). Platforms that are used less may be optimized less in GCC, so using another compiler that's been written for that platform can be faster.
But as a final summary: While there is ideal value in compiling on several compilers, in practice, this is mainly interesting for cross-platform software (and open-source software, because it often gets made cross-platform fairly quickly, and contributors have it easier if they can use their compiler of choice instead of having to learn a new one). If you need to ship on one platform only, shipping and maintenance are usually much more important than investing in building on several compilers if you're only releasing the builds made with one of them. However, you will want to clearly document any deviations from the standard (GCC-isms, for instance) to make the job of porting easier, should you ever have to do it.
Both Intel compiler and llvm are faster than gcc. The real reasons to use gcc are
Infinite hardware support (on no other compiler can you compile a lego mindstorm code on your old DEC).
it's cheap
best spagety optimizer in the business.

Using C++ in an embedded environment

Today I got into a very interesting conversation with a coworker, of which one subject got me thinking and googling this evening. Using C++ (as opposed to C) in an embedded environment. Looking around, there seems to be some good trades for and against the features C++ provides, but others Meyers clearly support it. So, I was wondering who would be able to shed some light on this topic and what the general consensus of the community was.
C++ for embedded platforms is perfectly fine - as long as you treat it as a better C. I love the fact that the language is slightly more structured. You can still do all the things that you want to do with C. Just remember to stick to an embedded C library like Newlib or uClibc.
I particularly like the abstraction that we can build using C++, particularly for I/O devices. So, we can have a class for UART and a class for GPIO and what nots. It is cleaner than having a bunch of functions (IMHO).
The fear of C++ among embedded developers is largely a thing of the past, when C++ compilers were not as good as C compilers (optimizations and code quality wise).
This applies especially to modern platforms with 32 bit architectures.
But, C is certainly still the preferred choice for more confined environments (as is assembler for 8 bit or 4 bit targets).
So, it really boils down to the resources your target platform provides, and how much of these resources you are likely to actually require, i.e. if you can afford the 'luxury' of doing embedded development in C++ (or even Java for that matter), because you know that you'll hardly have any issues regarding memory or CPU constraints.
Nowadays, many modern embedded platforms (think gaming consoles, mobile phones, PDAs etc), have really become very capable targets, with RISC architectures, several MB of RAM, and 3D hardware acceleration.
It would be a poor decision, to program such platforms using just C or even assembler out of uninformed performance considerations, on the other hand programming a 16 bit PIC in C++ would probably also be a controversial decision.
So, it's really a matter of asking yourself how much of the power, you'll actually need and how much you can afford to sacrifice, in order to improve the development experience (high level language, faster development, less tedious/redundant tasks).
It sort of depends on the particular nature of your embedded system and which features of C++ you use. The language itself doesn't necessarily generate bulkier code than C.
For example, if memory is your tightest constraint, you can just use C++ like "C with classes" -- that is, only using direct member functions, disabling RTTI, and not having any virtual functions or templates. That will fit in pretty much the same space as the equivalent C code, since you've no type information, vtables, or redundant functions to clutter things up.
I've found that templates are the biggest thing to avoid when memory is really tight, since you get one copy of each template function for each type it's specialized on, and that can rapidly bloat code segment.
In the console video games industry (which is sort of the beefy end of the embedded world) C++ is king. Our constraints are hard limits on memory (512mb on current generation) and realtime performance. Generally virtual functions and templates are used, but not exceptions, since they bloat the stack and are too perf-costly. In fact, one major manufacturer's compiler doesn't even support exceptions at all.
In my previous company all embedded code was written in a small subset of C code due to security (SIL-2) and memory reasons. By introducing a richer language like C++ in that particular scenario would have maybe cause more trouble than benefits.
In all due respect to C++ (which is a language I really love) but I think C - in our particular scenario - was the better choice.
I bet in some cases C++ is just fine to use for embedded applications but it really depends on the application - there is a difference if your program is controlling a nuclear plant or administrating an address book on your cell phone.
I don't know about "general consensus", only the company I work for (which does a lot of development for mobile phones, car navigation systems, DPFs, etc.).
The main drawback I've encountered to using C++ on embedded platforms as opposed to C is that it isn't quite as portable - there are many more cases of compilers that don't adhere to the standard which can cause problems if you need to build your code with more than 1 compiler or outright have bugs in the implementation. Then there are environments where C++ code simply won't run - BREW's issues with relocatable code and its "native OOP" don't play so well with "regular" C++ classes and inheritance.
In the end, though, if you're only targeting 1 platform, I'd say use whatever you think is "better" (faster, less bugs, better design) for your development - in most cases the issues can be worked around quite easily.
Depends what kind of embedded development you are doing. I've done embedded development with both C++, C, and Assembly on various platforms, you can even use Java to write applications on smart phones.
For instance on a smart phone like device that's running Windows CE 5, almost all of the code is C++, including in the operating system. Only small bits are written in C or assembly.
On the other hand I've written code for an MSP430 microcontroller, which was in C, and I probably would have done that in C++ had the compiler been more reliable and standards compliant.
Also I seem to recall a university lecturer of mine talking about writing embedded code in Forth or something. So really any language can do.
Now a days it will all boil down to the C++ runtime support of the platform. You're likely to find a way to compile C++ code down to almost any embedded platform with GCC, but if you can't find a suitable C++ runtime for the platform your efforts will be futile, unless you write your own C++ runtime.
One of the few things I tend to agree with Linus is his opinion about C++ http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918
Besides this, if you really really want to use C++ you might want to have a look at http://www.caravan.net/ec2plus/ which describes Embedded C++, or better to say you should not use in C++ for embedded systems.
The big thing keeping us with using C++ for a long time was the VxWorks support for it, which truly sucked. That supposidly has gotten better on VxWorks 6 (yes, it's been out a while... good 'ole vendor lock-in and lack of company vision has kept us stuck on VxWorks 5.5).
So for us it's mostly a question of the environment. After that, C++ can obviously be just as good as C... it's a matter of people understanding what their tool does and how to use it. C++ may make it easier to write incredibly inefficient code, but that doesn't mean we have to succomb to it.
I am currently fighting a problem with exceptions in an embedded Linux application. We are trying to port software written for a different platform that seemed to support exceptions well, but the new compiler tools (a port of gcc) reports errors when creating the eh_frame. I was against using exceptions for this tool, but the developer reassured me that modern compilers would support it well.
My opinion is that there are some advantages to C++, but I would stay away from exceptions and the standard template library. We haven't had problems using virtual functions.
C++ is suitable for microcontrollers and devices without an OS. You just have to know the architecture of the system and be conscious of time and space constrains, especially when doing mission critical programming.
With C++ you can do abstraction which often leads to an increased footprint in the code. You do not want this when programming for a resource-limited machine such as an 8-bit MCU.
Generally, avoid:
Dynamic memory allocation because it represents uncertainty in timing
Overloading
RTTI because the memory cost is large
Exceptions because of the execution speed lowering
Be cautious with virtual functions as they have a resource cost of a vtable per class and one pointer to the vtable per object. Also, use const in place of #define.
As you move up to 16 and 32-bit MCUs, with 10s or 100s of MB RAM, heavier features like the ones mentioned above may be used.
So to round up, C++ is useful for embedded systems. A main benefit is that OOP can be useful when you want to abstract aspects of the microcontroller, for example UART or state machines. But you may want to avoid certain features all of the time and some of the features some of the time, depending on the target you are programming for.