overloading address operator and standard containers

K

Kai-Uwe Bux

Hi folks,


please consider:


#include <list>

struct aaa {};

struct bbb {

aaa operator & ( void ) const {
return aaa();
}

};

int main ( void ) {
std::list< bbb > a;
}


Is this required to compile or is a compiler within its rights to reject the
code?

I recently posted a bug report and have been told that the code is invalid.
The address operator is supposed to be not overloaded. This, I have learned,
should follow from the provisions in C++03 about allocator::address(). I am
still trying to understand the reasoning, but I feel that I need some help.


Thanks

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Kai-Uwe Bux said:
Hi folks,


please consider:


#include <list>

struct aaa {};

struct bbb {

aaa operator & ( void ) const {
return aaa();
}

};

int main ( void ) {
std::list< bbb > a;
}


Is this required to compile or is a compiler within its rights to reject
the code?

I recently posted a bug report and have been told that the code is
invalid. The address operator is supposed to be not overloaded. This, I
have learned, should follow from the provisions in C++03 about
allocator::address(). I am still trying to understand the reasoning, but I
feel that I need some help.

One additional piece of information. I just found that
allocator<T>::address(x) has the return type T* or T const * and is required
to yield &x as the result. I could be deduced that operator& can at most be
overloaded so that the type is still bbb* (I would, however, think it could
be a defect in the standard). However, I bet that

struct bbb {

bbb* operator & ( void ) const {
return 0;
}

};

is problematic too. The question is: with the new code, is the code allowed
to exhibit undefined behavior?


Best

Kai-Uwe Bux
 
A

Alf P. Steinbach

* Kai-Uwe Bux:
Hi folks,


please consider:


#include <list>

struct aaa {};

struct bbb {

aaa operator & ( void ) const {
return aaa();
}

};

int main ( void ) {
std::list< bbb > a;
}


Is this required to compile or is a compiler within its rights to reject the
code?

It can reject the code.

I'm sure you can find the standard's requirements yourself, so I just mention
the infamous case of Microsoft's ATL workarounds for this issue. They originally
designed the ATL library with address operators overloaded, incompatible with
the standard C++ library. So now you know that it's real issue you can safely
invest the time to find the standard's requirements (if u still feel u need it).

I recently posted a bug report and have been told that the code is invalid.
The address operator is supposed to be not overloaded. This, I have learned,
should follow from the provisions in C++03 about allocator::address().

Uh, it's that way also in C++98.

I am
still trying to understand the reasoning, but I feel that I need some help.

Part of the reasoning is, I think, that with overloaded address operator any
container that does low-level things has to do CounterIntuitive Things(TM) to
obtain the real address of an object.

Say, you have a raw array of formal type T[n], where the first k elements are in
use, and you want to emplace an object at a[k]. With the T address operator
overloaded you can't just do ::new(&a[k])T(args). You have to do silly things
such as ::new(&reinterpret_cast<void&>(a[k]))T(args). Or, well, I guess you
could do ::new(a+k)T(args), but it's a bother when a+k and &a[k] mean two
different things. And presumably the standard library code shouldn't have to
guard against this...

The Boost library has some wrapper for the reinterpret_cast.


Cheers & hth.,

- Alf
 
J

James Kanze

please consider:
#include <list>
struct aaa {};
struct bbb {
aaa operator & ( void ) const {
return aaa();
}
};
int main ( void ) {
std::list< bbb > a;
}
Is this required to compile or is a compiler within its rights
to reject the code?

Objects in a standard container have to be CopyConstructible.
One of the requirements of CopyConstructible is that the
expression &t return a T* denoting the address of t, see
§20.1.3.
I recently posted a bug report and have been told that the
code is invalid. The address operator is supposed to be not
overloaded. This, I have learned, should follow from the
provisions in C++03 about allocator::address(). I am still
trying to understand the reasoning, but I feel that I need
some help.

The reasoning is another issue. Why CopyConstructible has this
requirement is beyond me. (If the restriction is necessary, for
some reason, it should be a separate requirement, with an
appropriate name, and not piggy-backed on top of
CopyConstructible. And off hand, I'm not sure why it's
necessary, although on the other hand, it sounds like a
reasonable restriction to me.)
 
K

Kai-Uwe Bux

James said:
Objects in a standard container have to be CopyConstructible.
One of the requirements of CopyConstructible is that the
expression &t return a T* denoting the address of t, see
§20.1.3.

Ah, thanks. That settles it.

The reasoning is another issue. Why CopyConstructible has this
requirement is beyond me.

I think, I found it. Consider std::list<T>. Usually, you will have nodes
like:

struct node {
T the_data;
node * next;
node * prev;
};

In iterator::eek:perator*() it is somewhat natural to return

&(current_node_ptr->the_data)

Other than this method, I don't think taking the address will appear.

In C++0x, this could be done portably using addressof().
(If the restriction is necessary, for
some reason, it should be a separate requirement, with an
appropriate name, and not piggy-backed on top of
CopyConstructible.
Agreed.

And off hand, I'm not sure why it's
necessary, although on the other hand, it sounds like a
reasonable restriction to me.)

I think, it's just the lack of addressof() in C++03. For std::list, you only
need to take the address once or twice in some 1000 lines of code. One could
do that easily using addressof() without turning the source into an
unreadable mess.

That said, I don't know whether C++0x still requires operator& to have its
original meaning for objects stored in containers.


Best

Kai-Uwe Bux
 

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
474,156
Messages
2,570,878
Members
47,413
Latest member
KeiraLight

Latest Threads

Top