tags:

views:

1266

answers:

8

Let me start with explaining what I mean with "magic". I will use two examples from Java:

  1. Every class inherits (directly or indirectly) the Object class.
  2. Operator overloading is not supported by Java but the + operator is defined for String objects.

This means that it is impossible to make an implementation of the Object and String classes in pure(*) Java. Now this is what I mean with "magic": to make an implementation of these classes, you will need some special support from the compiler.

What I always liked about C++ is that, as far as I know, there is no such "magic" going on in the STL, i.e. it is possible to implement the STL in pure C++.

Now my question is: is this true? Or are there parts of the STL that cannot be implemented in pure C++ and need some "magic"/special compiler support?


(*) With "pure" I mean without using any class libraries.

+46  A: 

in other words, has anything been done to the compiler to allow for a 'special case' the STL needed to work?

No.

It was all implemented as 'pure' C++ code, using the magic of templates.

There has been some work done to compilers to improve the STL (I'm thinking about various optimisations) but otherwise, no, you could write the entire STL if you really wanted. Some people did - STLPort is an implementation that didn't have the backing of any compiler manufacturer.

gbjbaanb
Well, most compilers needed to brush up their standard compliance... but, yeah.
delnan
"With C++, the magic WAS ALREADY THERE.", +1
mlvljr
A: 

STL is standard (Standard Template Library). The standard specifies the requirements for STL implementations. From the usage point of view, there is no "magic", no special dependencies you have to take care of. It can be used on any major C++ compilers, on all platforms supported by those compilers.

Cătălin Pitiș
But my question is whether the implementation of the STL itself needs any "magic" from the compiler.
Job
@Job: It needs a good standards conformant compiler.
Chubsdad
@Job: To support what has been said already: The **Magic** required from the compiler is **to be compliant to the implementation requirements** of STL, which is almost **any C++ compiler** out there and, aehm, which **complies to it**. Any old version of C++ compilers would not be able to handle the STL, almost any newer C++ compiler would. So thats like **Co-Evolution**.
rubber boots
@chubsdad: Good standards conformant compiler can be considered magic :) ...
Cătălin Pitiș
Any sufficiently advanced compiler is indistinguishable from magic.
Joe D
+2  A: 

As "gbjbaanb" rightly said, there is no magic involved in the implementation of STL. It is written in pure C++. You could implement it yourself but has been made readily available as a library to make your life simpler.

Swapnil
+31  A: 

Like gbjbaanb correctly said, the STL can be implemented in plain C++, without relying on any kind of compiler "magic".

However, if you go digging in the STL source code for your compiler, you'll probably see code that either isn't standard, or which you're not supposed to write yourself.

The STL can be implemented entirely in standard C++, but that doesn't mean compiler writers aren't allowed to improve it occasionally, using compiler-specific extensions. For example, they might insert non-standard code that ensures better error messages, or perhaps works around some flaw in their compiler, or maybe enables special optimizations by using extra features of that specific compiler.

They also consistently use names that you're not allowed to use. For example, template parameters are typically named something like _Type, which, since it starts with an underscore followed by a capital letter, is reserved for the implementation. The standard library is allowed to use them, but you and I are not. So if you were going to write your own STL implementation, you would have to make some minor changes, but that's not because of any magic, just a way to avoid name clashes between the standard library and user code.

jalf
Very nice answer! I'll let people vote for a while before I decide which answer to accept:-)
Job
Note that the "reserved" names are reserved by policy. This is not enforced by the compiler. You could use them if you wanted. As Jalf mentions, using these names runs the risk that your code will have name clashes with the libraries included in your compiler (or another one when someone else tried to compile your code), so obviously using them is a bad idea.
Brian
yup (I guess I should have mentioned that, but now you did such a good job of it, so +1 to you instead :))
jalf
+12  A: 

As others have said, the STL is implementable in pure standard C++98. What hasn't been said is that the development of the STL was concurrent with the development of the C++ template mechanism, and largely drove the inclusion of certain features. I believe that Argument Dependent Lookup (ADL, aka Koenig Lookup), template template parameters, and default template arguments all came to C++ to serve Stepanov's STL development.

So, with STL, they moved the magic into the language itself. Nice that the standards committee recognized that if those features were useful for what would become the standard library, they might be useful for the rest of us as well!

Drew Hall
+1: Thanks for the history lesson!
Job
If memory serves, ADL was separate (and even predates the proposal to standardize STL).
Jerry Coffin
@Jerry--I suspect you're right. I'm away from any relevant reference materials right now so I can't confirm. Maybe somebody can dig up a comprehensive list?
Drew Hall
+5  A: 

I'm pretty sure some type_traits require compiler magic, for example has_trivial_constructor, has_virtual_destructor or is_pod.

FredOverflow
Well, if that's true, I'd certainly like to know it! Does anybody know if these can be implemented in pure C++?
Job
well, those aren't in the current version of the standard. They are scheduled for inclusion in C++0x (and quickly skimming the draft didn't yield any info on how they might be implemented, so you may be right that they require compiler magic to implement -- on the other hand, their only purpose then is to *expose* this compiler magic so ordinary developers may use it. They don't keep it to themselves like @Job's Java examples do.)
jalf
I took a quick look at tr1 in which these are included. It seems the standard defines things that cannot be implemented in pure C++ as undefined behavior (please correct me if I'm wrong). For example, `is_pod` may return false negatives.
Job
Yes in C++0x there will be a few type traits that require compiler support, but I can't recall which ones. Those need Compiler support BECAUSE there is no way to implement them in pure C++.
Fabio Fracassi
@Job: that's TR1 though. the TR1 versions are library-only because they're basically adopted from Boost. They weren't basically the closest you could get without compiler support. C++0x takes it one step further and provides versions of these type traits that actually work correctly in *all* cases. And that can only be done through some unspecified form of compiler support.
jalf
+5  A: 

If by STL you mean only the template portion of the C++ standard library, then it is perfectly possible to implement it without any "magic". Whether each given implementation actually uses any "magic" is a different question (there are portions of STL, where "magic" would help, but not absolutely required).

Now, if you are talking about the entire C++ Standard Library, then it does indeed have a bit of "magic" in it. The classic example would be the library-provided ::operator new and ::operator delete implementations. We often call them "overloadable" in everyday language, while formally they are replaceable. C++ language does not offer such functionality to the user. The user cannot write a replaceable function.

Another example would be the offsetof macro (inherited from C Standard Library). While it is usually implemented in "pure C", the popular implementation is actually illegal form the pedantic point of view (causes undefined behavior). I haven't seen any formally legal implementations of offsetof, so I'm not sure whether they are even possible.

Another example would be (again, inherited from C) the macros for working with variable arguments. They obviously cannot be implemented in pure C or C++.

AndreyT
A: 

std::initializer_list needs compiler support and cannot be reimplemented as another class (as far as I know), though I'm not sure if it counts since it's in c++0x.

Neruz