tags:

views:

171

answers:

5

I have the following code compiled by gcc:

#include <iostream>
using namespace std;


class Buffer {
public:
   operator char *() { cout << "operator const * called" << endl; return buff; }
private:
    char buff[1024];
};


int main(int, char**) {
    Buffer b;
    (char *)b;  // Buffer::operator char * is called here

    return 0;
}

What I see is that Buffer::operator char * is called on line:

(char *)b;

Why C style cast calls Buffer::operator char * is called here?

I though that

static_cast<char *>(b);

should be used in order to invoke explicitly Buffer::operator char *.

+2  A: 

In C++, a C-style cast decides between static_cast, const_cast or reinterpret_cast depending on the type of the argument and the target type.

if you want a C cast, you need to use reinterpret_cast explicitly.

If you don't want the default behavior, specitfy the type of cast you want explicitely.

peterchen
+4  A: 

If you had done (char *)(&b) it would have been C style cast and operator char* will not be called. Here you are trying to cast an object into char*. Since there is no automatic conversion compiler looks for operator char* provided by you. If you had not provided it, you'll get a compiler error saying that Buffer can not be converted into char*

Naveen
+2  A: 

C++ Standard in 5.4/2 says that:

An explicit type conversion can be expressed using functional notation (5.2.3), a type conversion operator (dynamic_cast, static_cast, reinterpret_cast, const_cast), or the cast notation.

   cast-expression:  
      unary-expression  
      ( type-id ) cast-expression

You have cast expression here, which calls user defined cast operator.

Kirill V. Lyadvinsky
A: 

C-style casts in C++ really mean: Hey compiler, why don't you help me out here and figure out how best to convert to the target type? And, the compiler obliges. Here you have a conversion operator specified, which gets called because that's what the compiler thinks is best.

Note, that this neat little trick (of using C-style casts) should not be used until and unless you are absolutely sure of what you are trying to achieve.

dirkgently
+1  A: 

C-style casts makes compiler performs static_cast, const_cast, reinterpret_cast or some combination of them. To be more precise:

The conversions performed by

* a const_cast (expr.const.cast), 

* a static_cast (expr.static.cast), 

* a static_cast followed by a const_cast, 

* a reinterpret_cast (expr.reinterpret.cast), or 

* a reinterpret_cast followed by a const_cast,

can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply. If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed. If a conversion can be interpreted in more than one way as a static_cast followed by a const_cast, the conversion is ill-formed

As the rules are bit complicated it's better to avoid C-style casts in order to be sure what exactly is done.

Tadeusz Kopec