Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
420 views
in Technique[技术] by (71.8m points)

c++ - boost compressed_pair and addresses of empty objects

AFAIK, boost::compressed_pair is supposed to ensure that the address of the first and second memebrs are different while it does its magic of compressing the pair. It says so here. Seems like it is not the case and its behavior is different on different compilers. I'm using boost v 1.47. What am I missing?

struct E1 {};
struct E2 {};

boost::compressed_pair<E1, E2> diff_pair;
boost::compressed_pair<E1, E1> same_pair;

// clang++ and g++ 4.7 print the same address but VC2010 prints different addresses.
printf("different pairs = %p, %p
", &diff_pair.first(), &diff_pair.second());

// clang++ and g++ 4.7 print different addresses but VC2010 prints the same address.
printf("different pairs = %p, %p
", &same_pair.first(), &same_pair.second());
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When the types are different and one or both of the types is an empty class, the subobjects are supposed to be at the same address (if the compiler can pull the empty base class optimization off), that's the point of the compressed pair.

When the types are the same, I think a note from chapter 10 in the standard applies:

A base class subobject may be of zero size (Clause 9); however, two subobjects that have the same class type and that belong to the same most derived object must not be allocated at the same address (5.10).

So it seems it is up to the compiler to ensure that they are allocated at different addresses (and VC10 might be getting it wrong).

The comments in the boost's header indicate, that earlier they didn't bother to put two different instances of the same empty class in the compressed pair at all. Instead they just stored one instance and both first() and second() returned the same object.

   // 4    T1 == T2, T1 and T2 both empty
   //      Originally this did not store an instance of T2 at all
   //      but that led to problems beause it meant &x.first() == &x.second()
   //      which is not true for any other kind of pair, so now we store an instance
   //      of T2 just in case the user is relying on first() and second() returning
   //      different objects (albeit both empty).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...