Is C++'s new operator reentrant (or async-safe)? - c++

The background is in this question of mine. Put shortly, I have to fork in a multithreaded C++ program, so I'd like to figure out how much I can do when restricted to reentrant functions only, and one of the most essential things is dynamic memory.
So, malloc is known to be non-reentrant. But what about C++'s new? I googled for that with not many relevant results (mostly due to the difficulty to hit the correct "new"), but there is at least one claim that new is reentrant. There is also a relevant question concerning the whole C++ standard library with no satisfying answer.
Edit: I guess the standard didn't say anything about this, so I'm mostly concerned about major implementations.

I've looked at both the gcc libsupc++ and clang libc++ source, for replacing the standard-conforming C++ new/delete operators - to support native SIMD alignment requirements on platforms where it wasn't guaranteed by malloc.
They are basically wrappers for malloc and free with some EH logic, etc. I am not a language lawyer, but unless both have it wrong, I think it's safe to conclude: no, they are not reentrant.

Standard allows new to be just a wrapper around malloc, so if malloc can be not reentrant, so can new.

Thread-safety and re-entrance are not exactly the same.
AFAIK, the C++ ISO standard does not guarantee thread-safety for new and delete operators. But g++ implementation does provide thread-safetly (and it's one of the reasons it's slow).

Related

Why Embedded C++ compilers not support exceptions?

I was writing a library to embedded systems and I bumped into no STL standard library easy found.
But the worst news I receive is no exception support by compiler.
Atmel reference manual show this
Why not support exceptions on embedded environment?
It's simple make impossible to use a lot of libraries written in C++.
C++ is closely linked with exceptions, like with the new operator!
Obviously, nobody but the people that produce that compiler can really answer that question.
My best guess is that exceptions are both space- and time-consuming (time is only a real problem when the code throws, but space is needed for the unwind tables always, and can easily be about the same size as the overall code) for the compiled code, coupled with "rather difficult to implement", it's perhaps not the highest item on the list for the compiler developers, and thus not yet implemented. Whether it WILL be at some point in the future is obviously up to Atmel or whoever they subcontract to make their compiler.
I'm not an expert on Atmel C++ implementation, but I would be VERY surprised if the compiler supports throw, but not try/catch - since that would be about as useful as a screwdriver made from chocolate, when trying to fix the heater in a sauna that is stuck on full heat.
If you use the -fno-exceptions, the compiler should error if you have any throw in the code. And the STL can be compiled with -fno-exceptions - as that's how I compile my compiler code.
The 8 bit AtmelAVR with its limited ROM and RAM resources is not suited to the use of the STL which imposes a considerable load on both. Moreover C++ exceptions are intrinsically non-deterministic and therefore unsuited to many real-time applications.
A compiler may implement the EC++ (Embedded C++) "standard". The aim of EC++ was two fold:
to support the use of C++ in embedded systems at a time before ISO standardisation of the language, by restricting the language to a common subset available on all compilers.
to avoid non-deterministic (in both memory and timing) language/library features unsuited to hard-real-time applications.
Things missing from EC++ include:
namespace
templates
RTTI
exceptions
The omission of namespaces is entirely down to the first aim of EC++ and now essentially obsolete. The omission of the others are justified by both aims, and preclude the use of the STL and std::string libraries.
EC++ itself is now largely obsolete, but the subset it defines is nonetheless applicable to severely resource constrained targets, and many compilers support whole or partial EC++ enforcement.
Note that perhaps not all compilers for AVR impose these restrictions, but if you attempt to use these features extensively you will probably soon discover whey they are ill advised in most cases on targets very limited CPU and memory resources.
With respect to the use of the new operator, default dynamic memory allocation (as opposed to placement new or an override), is intrinsically non-deterministic and often best avoided in real-time embedded systems, and especially so where minimal heap is available. To use new without the assumption of exception handling, use new (std::nothrow) (#include <new>) which will not throw an exception but return a null pointer like malloc(). In EC++ new and new (std::nothrow) are essentially the same thing, but the latter is portable and explicit.
Lack of support for C++ in Atmel's maintained open-source library for GCC-AVR does not mean that there is no support for embedded systems in general, or indeed for AVR. IAR's AVR compiler supports what it refers to as Extended Embedded C++ (EEC++) as well as EC++. EEC++ does support a C++ library including STL with some modifications - no RTTI, no exceptions, and not in std:: namespace (although namespaces are supported). Support for ISO C++ as opposed to EC++ on most 32 bit targets is generally more comprehensive.

Stack allocator for C++03 standard containers

For a software I have to avoid any use of memory in the heap, and only rely on stack-allocated memory. Then, this prevents me from using any C++ standard containers, such as vector, map, string (well, basic_string), which I would really like to use, to ease development and data manipulation.
I found (many) implementations of stack allocators, such as this one which itself references two others, or this one from chromium.
Many of them are not fully compliant with the standard, or rely on C++11 (and I am stuck with C++03 at the moment, sadly). Do you have any feedback about a good already existing stack allocator for C++03 or should I adapt one of the above?
Thanks!
Howard Hinnant's short_alloc.h (see also here) is a pretty good start (you will need to add C++03 boilerplate, see here).
Of course, this will still go to the heap if it runs out of memory, the alternative is to throw std::bad_alloc.

C++0x lambda vs blocks

I was exploring C++0x today, and I encountered the new lambda feature. My question is how are these different (in terms of use) from blocks and why might one prefer one over the other?
Thanks.
there is a a short syntax with C++0x lambdas to take every variable in
scope by reference. ([&]) The type of a lambda is also unspecified,
allowing potentially more optimal code.
Now, when you look at Apple blocks, it will require __block specifiers
added to variables you want to modify (the very fact that this is
required suggests the whole system is defective). Variables are taken
by reference but then by value when the block exits the scope (and the
copied context necessarily lives on the heap, it seems). A weird
semantic that will only lead to broken designs, but probably makes
people that love GC happy. Without saying this probably has quite the
efficiency cost, of course, since this requires special indirections.
It is claimed the C++0x lambdas syntax would break compatibility with
C programs, but I don't think that is true. There are probably other
problems to integrate it with C, though, mainly the fact that C can't
really deal with unspecified types and build type erasure.
Apple blocks is really just an ObjC feature they try to generalize to
other languages. For C++, the system designed for that language is
just so much better.
EDIT:
To properly give credit, I took this information from http://www.rhinocerus.net/forum/language-c-moderated/558214-blocks-vs-c-lambdas.html a long time ago. That link is dead now; however, the original discussion appears to be archived here, thanks to #stefan for finding it.
I think it basically comes down to a question of your starting point. If you're starting from Objective-C, and writing C++ (Objective-C++) primarily (or exclusively) as an adjunct to Objective-C, then using blocks throughout all the code may make sense, simply to retain as much commonality as possible across the code base. Even if (for example) a project used some pieces written in Objective-C and others in C++, it could make sense to use blocks in both retain as much similarity throughout the code base as possible.
Unless you're using them outside of C++, however, I see little reason to prefer blocks over C++ lambdas. In what I'd guess to be the most common use (a predicate or action in an algorithm) the only noticeable difference between the two would be that one starts with ^ and the other with [].
Older versions of Objective C++
Before the ARC, there were internal differences in the implementation of blocks and lambdas that were likely to affect some more advanced uses. For example, blocks worked vaguely like C strings, so you used Block_copy to copy one, Block_release to free the copy, and so on. On the other hand, in C++ this is all automated so the copy ctor automatically uses Block_copy and the dtor Block_release as needed. At the same time, it did involve a bit more "magic", so (for example) when you copy a block, the copy is always allocated dynamically, regardless of how the source was allocated.
If, for one reason or another, you're stuck with using an older (I'm tempted to say "ancient") compiler or maintaining older code (and don't want to update the codebase as a whole) the memory management difference may be worth taking into account.
Mike Ash provides a detailed comparison. Blocks and lambdas differ in their syntax, their data type, the way they capture variables, the way they behave when copied, and their performance.
How they relate to C/C++/Objective-C:
I will refer to Apple's blocks extension as "Objective-C blocks" even
though this is not entirely correct. They are actually an addition to
C (and can even be used in C++), with some extra behaviors to make
them more useful in Objective-C. However, they are deeply intertwined
with Objective-C in their implementation, and "C blocks" is vague, so
I think that "Objective-C blocks" is the best way to refer to them
here.
C++0x lambdas are part of C++ only and can't be used from C.
Presumably they can be used in Objective-C++ if the compiler supports
C++0x.
A very high-level summary of the differences:
Objective-C blocks are somewhat simpler to write and to use,
especially in the case of using them for asynchronous or background
tasks where the block has to be copied and kept alive beyond the
lifetime of the scope where it was created. C++0x lambdas ultimately
provide more flexibility and potential speed, but at the cost of
considerable added complexity.
As of recent clang versions (3.2, 3.3rc and 3.4svn) they are interchangable in Objective-C(++) code. In C++ you have to use lambda, but in Objective-C(++) if you have
C++ support in your libobjc.
Apple's libobjc.B.dylib have it for sure. If you are using GNUstep, you need to either compile libobjc2 (and only libobjc2) with cmake and linking against libsupc++ (or whatever C++ ABI library you use) or link your project against libobjcxx as well
Blocks runtime should exist.
It is part of libSystem.dylib on OS X which libc is linked against so it is not much an issue there. You can use LLVM compiler-rt for this or use libobjc2. I personally recommend you use libobjc2 as it provided a Blocks runtime that is compatible with the rest of GNUstep, which is also called for.
Foundation kit.
This is due to how clang handle the ABI of interchanging C++ lambda and Objective-C blocks. clang do so with NSAutoreleasePool which is part of Foundation.
then you can safely interchange parts.

Implement the C standard library in C++

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.

Understanding memory management in mingw/g++

I was given an assignment to basically explain this. I have taken a quick look at the compiler documentation, and it seems to be a good place to start although it is quite extensive and I don't have much time. I'd like to know if I'd need to understand the C99 standards beforehand, or if there's another good source I can check. I'm going to be using it with Windows if it makes any difference. I also understand simple concepts such as heaps, stacks, linking and whatnot.
AFAIK, g++ is simply a C/C++ compiler, nothing more. memory is managed according to the standard C/C++ libraries.
Any decent C/C++ tutorial should give the basics for this information - but memory management in C/C++ is a huge topic. Surely for an entry level class your instructor would give some guidance & probably a more specific, less open-ended question.
g++ is just a compiler. It follows the rules of the language it compiles (In G++'s case, C++, but you also mention C99).
And for your fairly specific questions, you may need to
Consult the language standard (For C++ this is ISO/IEC 14882 ). Unfortunately not free, but you can find drafts online for free that are basically as good as the real thing. The latest official version is C++2003 (ISO/IEC 14882-2003), but contains only very minor changes from the original '89. C++09 is getting close to completion too, and again, there are drafts available online for this. Be warned though, it is heavy reading, and I wouldn't recommend trying to find anything there unless you're already very familiar with the language.
Analyze the assembler code the
compiler generates. The standard
leaves a lot up to the
implementation, so the only way to
find out how G++ specifically pushes
things onto the stack, in which
order and so on, is to analyze the
code it generates. (Also note that
this likely changes between
different versions of G++)
C++ is a notoriously underspecified language. There are huge chunks that just aren't covered by the standard, and where the compiler is free to do what it likes. This makes it a bit of a challenge to find out exactly what a given compiler is doing under the hood.
For this reason, you should also make sure you know exactly what you're expected to do. Dig up information on what the language says about memory management, or how g++ specifically deals with it?
I'm not clear on this question. If by "understanding memory management in mingw/g++" you mean "understand how the mingw g++ compiler handles memory internally while it is compiling files, such as when it allocates and frees abstract syntax tree nodes, etc.") then your answer is that as a multi-pass compiler GCC may not know the optimal lifetime for any particular piece of data but it does know that large groups of objects won't be needed from one pass to the other, so it uses memory pools when possible and garbage collection elsewhere.
On the other hand, if you're asking about how "how/when/what order ... objects, functions, variables, etc are put into the stack ... what is allocated and when and how this impacts performance" then you're in for a long night skimming through code.