I hope to add more light than heat to this discussion about C++ on bare metal and resource constrained systems.
Problems in C++:
Exceptions are especially a RAM problem as the required "emergency buffer" (where the out of memory exception goes for example) can be larger than the available RAM and is certainly a waste on microcontrollers. For more info see n4049 and n4234. They should be turned off (which is currently unspecified behavior so be sure and not ever throw). SG14 is currently working on better ways of doing this.
RTTI is probably never worth the overhead, it should be turned off
Large debug builds, although this is not a problem in classic desktop development if the debug does not fit on the chip it can be a problem. The problem arises from templated code or extra function calls added for clarity. These extra function calls will be removed again by the optimizer and the added clarity or flexibility can be a great advantage, however in debug builds this can be a problem.
Heap allocation. Although the STL allows for the use of custom allocators this can be complex for most programmers. Heap allocation is non deterministic (i.e. not hard real time) and fragmentation can lead to unexpected out of memory situations to occur despite having worked in testing. The book keeping needed by the heap in order to keep track of free space and varying size can be a problem with small objects. Its usually better to use pool allocation (both in C and C++) but this can be abnormal for C++ programmers used to only using the heap.
Runtime polymorphism and other indirect calls are usually a big performance hit, the problem is usually more because the optimizer cannot see through them more than the actual fetching and jumping to the address. Indirect calls are to be avoided for this reason in C and C++ where as in C++ they are more ingrained in the culture (and are quite useful in other domains).
implicit interfacing with clib can be problematic. It might be counterintuitive that clib problems are in the C++ category but the problem arises from implicit sharing of resources in concurrent environments (sharing is more explicit in C). Use of the common newLib implementation often drags in a lot of bloat which is usually not needed in uCs, on the other hand newLibNanno is not reentrant so access to it must be serialized (oversimplifying here). This is a problem for C as well but the access is more explicit. As a rule of thumb one should essentially use nothing from namespace std in ISR context unless you are sure it does not access state in clib somehow (errorno or the heap for example). Its also important if you are using threads (I prefer RTC) to override new and delete to synchronize access to malloc and free.
In conclusion C++ has some problems but they are essentially all fixable or avoidable.
Now for C, here the problem is higher order. I do not have the syntactic ability in C to abstract things in a way that I can perform optimization or check invariants at compile time. Therefore I cannot properly encapsulate things in a way that the user does not need to know how they work in order to use them and most of my error detection is done at runtime (which is not only too late but also adds cost). Essentially the only way to be generic in C is through data, I pass a format string to printf or scanf which is evaluated at runtime for example. It is then quite hard for the compiler to prove that I am not using some of the options which are theoretically possible when passed the right data which means potential dead code generation and loss of optimization potential.
I know I may be unleashing a shitstorm here but my experience on 32 bit microcontrollers is that in an apples to apples comparison of C and C++ both written by experts (as in C++ potentially highly templated) C++ is the much more efficient language as soon as anything needs to be at all generic (as in any library) and they are essentially equivalent in non generic cases. It is also easier for a novice to leverage the expertise of an expert library implementer in C++.
At the same time there are actually truly few functions to which I cannot pass incorrect data, as soon as the input is not an int but a something
for which I happen to be using an int as a method of representation then there is a potential get it wrong (pass an invalid value or an 'otherThing' rather than a 'something'). In C my only method of checking if the user got it wrong is at runtime. In C++ I have the ability to perform some checks, not all checks but some checks at compile time which are free.
At the end of the day a C team is often as powerful as its weakest programmer and the resulting code's benefit has either a multiplayer of 1 or a performance penalty. What I mean by this is it is either high performance for one and only one unique job in a unique environment of unique design decisions or it is generic enough to be used in multiple environments (other microcontroller, other memory management strategy, other latency vs. throughput trade offs etc. etc.) but has an inherent performance cost.
In C++ things can be encapsulated by experts and used in many environments where compile time code generation adapts to the specific task and static checking keeps users from doing stupid stuff at zero cost. Here we have far less trade off between being generic and being fast and thus ultimately from an cost vs. benefit standpoint are the more performant, safer and more productive language.
It is a valid critique that there is still a great shortage of good C++ libraries for embedded, this can lead to pragmatic decisions to use mostly C on a C++ compiler. Decisions to use only C in a project are essentially either ideologically driven, out of need for legacy support or an admission that the team is not disciplined enough to refrain from a very select set of stupid things which one can do in C++ but not in C and at the same time disciplined enough to not do any of the far greater set of stupid things which one cannot guard against in C but could in C++.