auto_ptr and operator void*();

G

Gianni Mariani

David said:
David said:
[...]
Unless there is a defined conversion from int* to
MuthaObject*, I think it should elicit a diagnostic.

Maybe, but it is perfectly legal C++ (except for a typo I
just noticed).


I'm not sure what's so legal about it:

class MuthaObject { };

int main()
{


This was posted (typo fixed).
int* p = new int(42);
void* q = static_cast<void*>(p);
MuthaObject * r = static_cast<int*>(q);
delete r;

and you tried this ?
MuthaObject* p = new int;
}

"ComeauTest.c", line 5: error: a value of type "int *" cannot
be used to initialize an entity of type "MuthaObject *"
MuthaObject* p = new int;

I don't think you're testing what I posted.

Of course. What does that have to do with void*?


Maybe I mis-understood what you meant by

"the information must be saved somewhere".

What did you mean by that ?
Not sure what you're talking about here. I'm talking
about:


Specifically, the compiler MUST NOT apply a conversion from int * to
MuthaObject* (even if one exists) to be compliant to the standard with
the code snippet I posted.

MuthaObject * r = static_cast<int*>(q);

[...]
That's an interesting question. Theoretically, the
compiler *could* always keep track of what void* are
pointing to, but I'm not sure they are required to do so,
which is probably why it results in undefined behaviour.

I don't think you can. There are paths of data that are
outside the control of the conmpiler.


Such as?

Libraries, files, devices ...
 
D

David B. Held

Gianni Mariani said:
David said:
[...]
I'm not sure what's so legal about it:

class MuthaObject { };

int main()
{


This was posted (typo fixed).
int* p = new int(42);
void* q = static_cast<void*>(p);
MuthaObject * r = static_cast<int*>(q);
delete r;

and you tried this ?
MuthaObject* p = new int;
}
[...]

I don't think you're testing what I posted.

I'm testing the part that I thought should cause a diagnostic
to be emitted, which was the assignment of an int* to a
MuthaObject*.
[...]
Maybe I mis-understood what you meant by

"the information must be saved somewhere".

What did you mean by that ?

I mean the compiler must keep track of pointer type
information somewhere in order to do valid casts to void*
and back. But technically, I guess that's not the case.
The compiler could just assume that you perform casts
correctly, and invoke undefined behaviour if you don't.
[...]
Specifically, the compiler MUST NOT apply a
conversion from int * to MuthaObject* (even if one
exists) to be compliant to the standard with the code
snippet I posted.

So what's your point?
[...]
I don't think you can. There are paths of data that are
outside the control of the conmpiler.

Such as?

Libraries, files, devices ...

I don't think you can read pointers from a file and expect
them to work properly, but I will buy that a pointer passed
over a DLL/so boundary will probably not have any
special type information.

Dave
 
R

Rob Williscroft

Gianni Mariani wrote in
I think it does.

[snip]

Thanks for the code, as an aside I got:
<aside>

bcc32:
Allocate size is 16
Allocate size is 480
delete size is 16
delete [] size is 16

g++:
Allocate size is 8
Allocate size is 244
delete size is 8
delete size is 244

cl:
Allocate size is 8
Allocate size is 240
delete size is 8
delete [] size is 8

g++ takes an extra 4 bytes for the size-of info it passes back.

1 out of 3 got delete [] right. I mostly consider cl to be my most
conforming compiler ( It does 2-Phase lookup if you prod it just right )
but then gcc comes along and does this.

Admittedly it's an optional parameter

Size info never gets passed on to the to ::eek:perator delete i.e. the
inbuilt "free-store" has to retain any size-of information that it might
require.

In general a compiler has to be able to compile delete expresions
where it is unable to pass size or any other info other than the
pointer to operator delete.
BUT it is available and I've seen
some really KULE allocators that use this information when managing
extreme numbers of tiny objects and saving big time on memory and
cycles.


Most of the time.



delete ptr

and

operator delete( ptr )

are 2 different things.

delete ptr also calls the destructor (if it exists) while operator
delete( ptr ) simply calls the method "operator delete( ... )".

delete (void *)ptr; will call ::eek:perator delete( ptr ) and nothing else.
It will do this even when in a class scope that defines a member
operator delete.

Rob.
 
S

Sektor van Skijlen

# Is there any reason why auto_ptr does not have the cast operator like this:

# operator void* ();

# So that one could easily test auto_ptr for NULL ???
# Standard does not declare such operator.

Right. Moreover, such an operator will not allow you to compare the inside
pointer against NULL. At least because NULL is not a 'void*' value, but
'int' value.

To be able to compare the inside pointer against NULL, the auto_ptr template
had to provide appropriate '==' operator with 'int' as an argument. This also
does not matter if you use the deprecated NULL constant, or - as recommended
- directly 0.

I think also that this problem is wider and is a more global problem with
null pointer value. Neither 0 nor NULL is a good way to check the pointer
against null pointer value. You can find a better definition of 'null'
symbol at:

http://www.intercon.pl/~sektor/cbx/generic/templates.html

Search for "NULL" string there; the definition is below that line.
(any suggestions welcome ;)


# Is the only way to check if auto_ptr points to NULL, is to use .get() method
# ?

By standard methods, yes.


--
1 6 1 7 4 4 2 548 g4bc7a4 66z 3xt7w v1y z9p1 120 32
(( Michal "Sektor" Malecki w4 66 64 73 7564 24 5 v 34 4
)) ektor van Skijlen 1 5 5 1 844 a v r z 4
Software engineer, Motorola GSG Poland 1 2 2a 1 4
WARNING: Opinions presented by me on usenet groups are my personal opinions
ONLY and are not connected to the employer.
 
R

Ron Natalie

Sektor van Skijlen said:
Right. Moreover, such an operator will not allow you to compare the inside
pointer against NULL. At least because NULL is not a 'void*' value, but
'int' value.

Huh? Of coruse it's not a void* value, but it's comparable to one. An
arbitrary object pointer that is a null pointer, converted to another object pointer
(like void*) is the null pointer and can be compared against the null pointer
constant (NULL).
To be able to compare the inside pointer against NULL, the auto_ptr template
had to provide appropriate '==' operator with 'int' as an argument. This also
does not matter if you use the deprecated NULL constant, or - as recommended
- directly 0.

Nonsense, the overload would not be needed. NULL is NOT deprecated.
I think also that this problem is wider and is a more global problem with
null pointer value. Neither 0 nor NULL is a good way to check the pointer
against null pointer value.

It works, the major problem is that it's confusable with integers in overloading
contexts.

You can find a better definition of 'null'

I don't speak Polish.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top