I'm stuck in Stevenage all week teaching a C++ course to ten engineers. Right now I am dicking with the hired laptop while they do exercises. Occasionally I come up with interesting C++ nastinesses to show them.
Just now I was talking about a hypothetical overloaded operator+
function, and trying to show how the compiler translates uses of +
into calls to that function. I wrote a method call on the whiteboard and
someone asked me if you could actually use that type of call directly.
Well, I thought not, but you can never be sure with C++, so I tried it.
It turns out that this is entirely valid (according to G++ 3.0):
#include <iostream> using namespace std; class Foo { public: int operator+ (int i) const { return 23; } }; int main () { Foo f; cout << f.operator+(42) << endl; }
Oh, getting close to lunchtime. If I can just look alert for a few more
minutes I'll be able to sneak off for a cig :-/
Back from lunch: and one of the students suffers from a seg fault.
I see nothing wrong for a while, but eventually spot a strange initialiser
list where they've constructed a string object from the numeric
literal 0. I ponder how this could work, and eventually realise that
it's not a numeric literal, but a pointer literal. The compiler thinks
this is fine, because a string object can be constructed from a
char* value, and the token 0 can be interpreted as a null
pointer of any pointer type. So much for type safety.
Just to illustrate, this is entirely valid, and compiles without warnings even in maximum paranoiac mode, but crashes because of a null pointer dereference:
#include <iostream> #include <string> using namespace std; int main () { string foo (0); cout << foo << endl; }