Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

void * operator

0 views
Skip to first unread message

jsh...@bigfoot.com

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Hi,
Let's say I need a class with the foll functionality
class A { /* */ };
A a;

if(a)

I can achieve this in various ways
for eg.
overloading operator void *() in class A, or operator bool () or
operator int ().

Does it make any difference which of the above operators I choose
to overload to get this functionality.

I ask, becos, according to BS's book for the stream classes, overloading
operator void *() is used to get this functionality. I would have thought
operator bool () would been the logical choice, because, if all the 3 exist,
the compiler would pick operator bool() over the others ( at least EGCS does
this)

Does the standard specify which of these operators has to be overloaded in
the streams class ? Or is it left to the implementer ?

Is bool() not the obvious choice, because, many compilers do not implement it,
or is there some other reason ?
Even then, wouldn't int() be the next choice ?

--
rgds,
Shiva
comp.lang.c++ FAQ :http://www.cerfnet.com/~mpcline/c++-faq-lite/
http://members.xoom.com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Vesa Karvonen

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
In comp.lang.c++ jsh...@bigfoot.com wrote:
> Hi,
> Let's say I need a class with the foll functionality
> class A { /* */ };
> A a;

> if(a)

> I can achieve this in various ways
> for eg.
> overloading operator void *() in class A, or operator bool () or
> operator int ().

[snip]


> Is bool() not the obvious choice, because, many compilers do not implement it,
> or is there some other reason ?
> Even then, wouldn't int() be the next choice ?

Neither the bool() nor the int() are good choices because bools and
ints they have lots and lots of operators related to them. This means
that in addition to enabling the desired "if (a)" functionality, you
would also enable stuff like "a+b", "a < 1",... Essentially, everything
that you can do with an integral arithmetic type. The set of things
you can accidentally do with a void*() is much smaller, so it is
much safer.

In C++, it is easy to construct components, which make many things
happen using implicit conversions and operators. Unless such a
component is very carefully constructed, it can easily become a
nightmare for a maintainer, because it becomes very difficult to
determine which implicit conversion(s) is/are taking place. This is
one of the reasons why the keyword "explicit" was adopted to C++. In
general, one should be extra careful while introducing conversion
operators or constructors into a component.

(By "component", I'm referring to a set (i.e. a library) of related
classes, functions and other primitives.)

<--->
Vesa Karvonen

Jim Gewin

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
jsh...@bigfoot.com wrote:
>
> Hi,
> Let's say I need a class with the foll functionality
> class A { /* */ };
> A a;
>
> if(a)
>
> I can achieve this in various ways
> for eg.
> overloading operator void *() in class A, or operator bool () or
> operator int ().
>
> Does it make any difference which of the above operators I choose
> to overload to get this functionality.
>
> I ask, becos, according to BS's book for the stream classes, overloading
> operator void *() is used to get this functionality. I would have thought
> operator bool () would been the logical choice, because, if all the 3 exist,
> the compiler would pick operator bool() over the others ( at least EGCS does
> this)
>
> Does the standard specify which of these operators has to be overloaded in
> the streams class ? Or is it left to the implementer ?
>
> Is bool() not the obvious choice, because, many compilers do not implement it,
> or is there some other reason ?
> Even then, wouldn't int() be the next choice ?
>
[ signature snipped ]

One thought: a bool will implicitly convert to
an arithmetic built-in type, while a void* will
not. Surely you don't want people to say
int x = std::cout + 3;
(More likely it was for some reason I can't
think of, but this seems fairly important to
me.)
Anyway, the standard does specify basic_ios<>
to have an operator void*.

Nathan Myers

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
<jsh...@bigfoot.com> wrote:
> Let's say I need a class ... class A { /* */ }; A a; if(a) ...
>
>I can achieve this [by] overloading operator void *() in class A,
>or operator bool () or operator int ().
>Does it make any difference which of the above operators I choose
>to overload to get this functionality.
>
>Does the standard specify which of these operators has to be overloaded
in
>the streams class ? Or is it left to the implementer ?

It specifies operator void*().

>Is bool() not the obvious choice, because, many compilers do not
implement it,
>or is there some other reason ?
>Even then, wouldn't int() be the next choice ?

Defining a conversion to a numeric type is usually a serious error.
The problem is that numeric types convert promiscuously to other
numeric types, so a conversion to bool is also a conversion to int,
double, and what-have-you. (Of course, the promiscuous conversions
of numeric types were inherited from C, though in principle bool
could have had somewhat different behavior.)

If iostreams had an operator bool then the following statements would
be legal, and would not generally even produce a warning:

cin << i; // oops
cout >> i; // oops again.

The streams would be converted to bool and then int, and then the
built-in operators << and >> would be used.

The operator void*() does not suffer from this problem, so if all you
want to do is use the class in a conditional context, operator void*
is a better choice.

--
Nathan Myers
n...@nospam.cantrip.org http://www.cantrip.org/

Francis Glassborow

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
In article <75sjbo$sms$1...@nnrp1.dejanews.com>, jsh...@bigfoot.com writes
>Hi,
> Let's say I need a class with the foll functionality

>class A { /* */ };
>A a;
>
>if(a)
>
>I can achieve this in various ways
>for eg.
>overloading operator void *() in class A, or operator bool () or
>operator int ().
>
>Does it make any difference which of the above operators I choose
>to overload to get this functionality.

You bet it does, and there is a story behind it. Soon after bool was
added to the language those responsible for developing the library part
of the standard changed istream and ostream so they had an operator bool
instead of the operator void const *. It was very rapidly changed back
but not before a couple of compilers were released that allowed you to
write:

int i = cout+cin;

You need a type for which there are no automatic conversions. the only
one that meets that need is void * and qualifications of it. By using
void const * you ensure that it the value can only be used for its
intent.


Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Gargantua Blargg

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
(A copy of this message has also been posted to the following newsgroups:
comp.lang.c++.moderated, comp.lang.c++)

[want functionality that allows object to be in if statement as "if ( obj
) ..."]

OK, we don't use bool or int for obvious reasons (obj ain't a numeric
type, but more a pointer type in that it can have a null value, but can't
be used in normal arithmetic). But void* also seems like a bad choice,
too, because functions sometimes take a void* as an untyped argument.
However, it is unlikely we *ever* want to pass obj as a void*. Having
faced this situation recently, I decided void const volatile* was a better
type, since there isn't a conversion to void*, and it would be *very*
unlikely a function would take an argument of this type :-)

The implementation of the operator is also simple enough, as it can return
the this pointer if non-null (there is an implicit conversion from any
pointer to a void const volatile*).

Summary: operator void const volatile* () const seems like a better choice
than operator void* () because some functions take void*, but probably
never take void const volatile*.

Expressed in code:

class X {
public:
operator bool () const;
};

void f()
{
X x;
if ( x ) { } // OK, good so far
if ( !x ) { }

bool b = x; // nope, don't want this

int i = x; // oops. not good (implicit conversion from bool to int)
}

// same goes for X having an operator int ()

// OK, how about void*?

class X {
public:
operator void* () const;
};

void operate_on_raw_obj( void* );

void f()
{
X x;
if ( x ) { } // OK, good so far
if ( !x ) { }

//int i = x; // not allowed, good

new (x) int; // not good, x converts to void*

memcpy( x, x, 1 ); // not good, memcpy takes void* too

operate_on_raw_obj( x ); // argh!
}

// Fine, try void const volatile* !

class X {
public:
operator void const volatile* () const;
};

void operate_on_raw_obj( void* );

void f()
{
X x;
if ( x ) { } // OK, good so far
if ( !x ) { }

//int i = x; // not allowed, good

//new (x) int; //not allowed, good

//memcpy( x, x, 1 ); // not allowed, good

//operate_on_raw_obj( x ); // not allowed, good!
}

// implementation of operator is simple:

X::operator void const volatile* () const
{
return this->are_we_null() ? NULL : this;
}

Comments?

--
Gargantua Blargg | bla...@flash.net | http://www.flash.net/~blargg/

Ian Collins

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
jsh...@bigfoot.com wrote:

> Hi,
> Let's say I need a class with the foll functionality
> class A { /* */ };
> A a;
>
> if(a)
>
> I can achieve this in various ways
> for eg.
> overloading operator void *() in class A, or operator bool () or
> operator int ().
>
> Does it make any difference which of the above operators I choose
> to overload to get this functionality.
>

> I ask, becos, according to BS's book for the stream classes,
overloading
> operator void *() is used to get this functionality. I would have
thought
> operator bool () would been the logical choice, because, if all the 3
exist,
> the compiler would pick operator bool() over the others ( at least
EGCS does
> this)
>

> Does the standard specify which of these operators has to be
overloaded in
> the streams class ? Or is it left to the implementer ?
>

> Is bool() not the obvious choice, because, many compilers do not
implement it,
> or is there some other reason ?
> Even then, wouldn't int() be the next choice ?

Would it not be better to use a bool member ok() ?

I would tend to avoid operator void*(), it could result in some

stange and difficult to find run time bugs if the compiler uses

it in unexpected places.

--
Ian Collins
Violet Cottage, Button End
Harston, Cambs
UK.

Siemel Naran

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to
On 25 Dec 1998 17:19:44 -0500, Ian Collins <i...@masuma.com> wrote:
>jsh...@bigfoot.com wrote:

>> I can achieve this in various ways
>> for eg.
>> overloading operator void *() in class A, or operator bool () or
>> operator int ().

Others have explained why overloading void* is better than
overloading bool. In short, there is very little you can
do with a void*, but more that you can do with a bool. You
can compare a void* to zero, but you can't increment a void*
(because sizeof(void) is undefined), can't subtract two
void*. In addition, I prefer the following,
operator const void*() const;


>Would it not be better to use a bool member ok() ?

Generally, this is better, but it may be a little inconvenient
at times as you have to type "if(a.ok())", rather than "if(a)".


>I would tend to avoid operator void*(), it could result in some
>stange and difficult to find run time bugs if the compiler uses
>it in unexpected places.

There's the possibility for someone to static_cast the void*
back into something useful. Provided we don't do dangerous
things like these, the void* return is better.

Since operator void* returns "this" or the address of some
member variable, the following may be always false
(a==b); // may be always false
The "a" calls a.operator void*. Suppose it returns #true
which is expressed as the address of a.x. Similarly, "b"
calls b.operator void*. Suppose it also returns #true
which is expressed as the address of b.x. Perhaps the
expression "a==b" should be true as both 'a' and 'b' are
#true. But as a.x and b.x have different addresses, the
result may be #false. The #false may make sense, but it
is something to think about.

--
----------------------------------
Siemel B. Naran (sbn...@uiuc.edu)
----------------------------------

James Slaughter

unread,
Dec 29, 1998, 3:00:00 AM12/29/98
to

Francis Glassborow wrote in message ...

>
>In article <75sjbo$sms$1...@nnrp1.dejanews.com>, jsh...@bigfoot.com
writes

>>


>>I can achieve this in various ways
>>for eg.
>>overloading operator void *() in class A, or operator bool () or
>>operator int ().
>>

>>Does it make any difference which of the above operators I choose
>>to overload to get this functionality.
>

>You bet it does, and there is a story behind it. Soon after bool was
>added to the language those responsible for developing the library
part
>of the standard changed istream and ostream so they had an operator
bool
>instead of the operator void const *. It was very rapidly changed
back
>but not before a couple of compilers were released that allowed you
to
>write:
>

>int i = cout+cin;
>

How does this carry over into the context of relational operators and
other would-be-boolean functions? Should I be writing 'void const *
operator < ()', or is code like 'int i = (myThing < 5)+4;'
suspiciously dodgy enough to let me get away with just 'bool'?


>You need a type for which there are no automatic conversions. the
only
>one that meets that need is void * and qualifications of it. By
using
>void const * you ensure that it the value can only be used for its
>intent.
>


Hmm... another question. Should one ever define 'operator ! ()', or
should the status of a class be black and white in this respect? Are
there any cases where defining 'operator void const *' doesn't work?

As an aside, my compiler allows me to define certain operators as not
having a return type... is it supposed to, or is it just an overthrow
from when 'int' was an implicit return type? Is it better to write the
return type anyway?


Regards,
James Slaughter

Francis Glassborow

unread,
Dec 30, 1998, 3:00:00 AM12/30/98
to
In article <914899599.15207.1...@news.demon.co.uk>, James
Slaughter <James.S...@susano.demon.co.uk> writes

>
>Francis Glassborow wrote in message ...
<snipped>

>>int i = cout+cin;
>>
>
>How does this carry over into the context of relational operators and
>other would-be-boolean functions? Should I be writing 'void const *
>operator < ()', or is code like 'int i = (myThing < 5)+4;'
>suspiciously dodgy enough to let me get away with just 'bool'?

one reason for bool havine those sickening outward conversions was to
support all those places where programmers had written such code:)

>
>
>>You need a type for which there are no automatic conversions. the
>only
>>one that meets that need is void * and qualifications of it. By
>using
>>void const * you ensure that it the value can only be used for its
>>intent.
>>
>
>
>Hmm... another question. Should one ever define 'operator ! ()', or
>should the status of a class be black and white in this respect? Are
>there any cases where defining 'operator void const *' doesn't work?

I think this is substantially a matter of style. If I was worried about
providing a conversion operator even to void const * I would resort to
operator !()


>
>As an aside, my compiler allows me to define certain operators as not
>having a return type... is it supposed to, or is it just an overthrow
>from when 'int' was an implicit return type? Is it better to write the
>return type anyway?

I suspect that this is a side effect of conversion operators. While not
difficult, implementors have to distinguish between uses of the operator
keyword. Where we have a genuine operator a return value is required,
where we have a conversion operator an explicit return type would be an
error.


Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

0 new messages