views:

150

answers:

3

I have the following class:

class MyClass {
public:
   MyClass( char* what ) : controlled( what ) {}
   ~MyClass() { delete[] controlled; }
   operator char*() const { return controlled; }
   operator void*() const { return controlled; }
   operator bool() const { return controlled != 0; }

private:
   char* controlled;
};

This is compiled with Microsoft SDK that has the following typedefs:

typedef long LONG_PTR;
typedef LONG_PTR LPARAM;

The calling code does the following:

MyClass instance( new char[1000] );
LPARAM castResult = (LPARAM)instance;
// Then we send message intending to pass the address of the buffer inside MyClass
::SendMessage( window, message, wParam, castResult );

Suddenly castResult is 1 - MyClass::operator bool() is invoked, it returns true which is converted to 1. So instead of passing the address I pass 1 into SendMessage() which leads to undefined behaviour.

But why is operator bool() invoked in the first place?

+11  A: 

It's one of the known pitfalls of using operator bool, that is a aftershock of C inheritance. You'd definitively benefit from reading about the Safe Bool Idiom.

In general, you didn't provide any other matchable casting operator, and bool (unfortunately) is treated as a good source for arithmetic casting.

Kornel Kisielewicz
+5  A: 

operator bool is the best match, because char* and void* can't be converted to long without an explicit cast, unlike bool:

long L1 = (void*)instance; // error
long L2 = (char*)instance; // error
long L3 = (bool)instance; // ok
Samuel_xL
+2  A: 

You cannot implicitly cast a T* to long. But you can cast a bool to long.

So the operator bool is used.

You have to define a operator LPARAM.

Christopher
Or rather remove all of the conversion operators. Only `operator void*` is considered relatively benign if you wish to allow evaluating the object in boolean context (used in standard C++ library, but makes for example `std::cout << std::cin;` produce somewhat unintuitive results), even though there are even surer techniques.
visitor