Is (&(*(T*)0)) UB ?

G

Gianni Mariani

So I have a situation where I have all kinds of smart pointer types that
have an "*" deref operator and I want to create a simple template to
assign to any of them.

// ======== DerefTypeAssign ===========================================
/**
* This discovers the type of the dereferenced pointer and then assigns
* a dynamically downcasted version of the other.
*
* @return nothing
*/

template <typename w_Type, typename w_DerefType, typename w_Parent >
inline bool DerefTypeAssign(
w_Type & o_dest,
w_DerefType * i_ignored,
w_Parent * i_parent_ptr
) {

w_DerefType * l_newp = dynamic_cast< w_DerefType * >(i_parent_ptr);

if ( ! l_newp )
{
return false;
}

o_dest = l_newp;

return true;
}


Usage is from a template:

template <typename w_Type>
class ResolverReference
{

.....

w_Type & ref;

template <typename w_XX>
bool FixRef( w_XX & foo )
{
return DerefTypeAssign( ref, &*ref, &*foo );
}
};


here is it quite possible that ref has a null pointer.

OK OK - if according the the standard it's UB, does anyone know of a
practical situation where it would not work ?

I really really wish we had "typeof" ...

FYI, this is for some reference fix up code... In the input file all
the objects have names and they come in in any order. For simplicity I
want to have regular classes with regular members. As the objects are
read in, all the references (pointers, smart or not) are placed into a
resolver. The act of resolving is by calling the "FixRef" method above.

Anyone have a better idea ?
 
F

Frederick Gotham

Gianni Mariani:
Re: Is (&(*(T*)0)) UB ?

You are:

(1) Taking a null pointer.
|_
|
(2) Dereferencing it.
|_
|
(3) Taking its address.

Something similar is the following:

int arr[5];

int *p = arr+5;

The behaviour of the snippet immediately above is well-defined, because we
can play around with the address to "one past last". However, if we change
it to:

int *p = &arr[5];

, then its undefinedness is brought into doubt, because we're not allowed
to dereference the pointer to "one past last". (You should not that the
expression is equivalent to:

int *p = &*(arr+5);

Enough people thought that the undefinedness of this was ridiculous to
compel the people at the C Standard to say that the behaviour is well
defined, as no dereference shall take place if its followed immediately by
an addressof.

As regards C++ though, the Standard does not define its behaviour.

As for the practicality of the situation, well I suppose one could fathom a
computer which has a CPU or OS which detects a null pointer access and
shuts the program down. That said though, an optimiser may remove the
dereference because it's made redundant by the addressof which follows
immediately afterward.

Long story short, you should avoid invalid dereferences if you can. I
wonder what percentage of implementations it would cause a problem with
though... less than 5%?
 

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

No members online now.

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top