Using &
to get an address of a variable can be problematic if the variable type has overloaded operator&()
. For example, _com_ptr_ has operator&()
overloaded with a side effect of modifying the object.
Now I have a complicated set of templates with functions like this:
template<class T>
void process( const T* object )
{
//whatever
}
template<class T>
void tryProcess( T& object )
{
process( &object )
}
In tryProcess()
I need to get a T*
pointer holding the address of the actual object of type T
.
The above implementation of tryProcess()
will only work allright if class T
doesn't have operator&()
overloaded. So if I call tryProcess<_com_ptr_<Interface>>()
I can get unexpected results - the overloaded operator&()
is triggered.
In another question the following workaround is suggested:
template<class T>
T* getAddress( T& object )
{
return reinterpret_cast<T*>( &reinterpret_cast<char&>( object ) );
}
With such a function I can implement tryProcess()
as follows:
template<class T>
void tryProcess( T& object )
{
process( getAddress( object ) )
}
and will always get the same behavior independent of whether class T
has operator&()
overloaded. This introduces zero overhead with optimizations on on Visual C++ 7 - the compiler gets what to do and just gets the object address.
How portable and standard-compilant is this solution to the problem? How could it be improved?
To access the address of a variable to a pointer, we use the unary operator & (ampersand) that returns the address of that variable. For example &x gives us the address of variable x.
If you just want to print the address to stdout , just do the following: printf("%p\n", &sum); The format specifier %p allows you to pass a pointer, and you can use &sum directly to pass the value of the address of sum .
The Address Operator in C also called a pointer. This address operator is denoted by “&”. This & symbol is called an ampersand.
Boost addressof
is implemented with that reinterpret_cast
trick so I'd say it's probably portable and standard-conforming.
Here you can see the code in question.
It is standard-complaint. The issue was brought to the attention of the ISO C++ committee in relation to problems with offsetof
implementations that broke on this. Amongst the solutions considered were tightening the POD definition, or adding an extra restriction on types to be used with offsetof
. Those solutions were rejected when the reinterpret_cast
solution was brought up. Since this offered a standard-compliant way around the problem, the committee did not see a need to add extra requirements to the offsetof
, and left fixes to the implementations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With