увеличить сжатый_пар и адреса пустых объектов - PullRequest
6 голосов
/ 08 октября 2011

AFAIK, boost ::ressed_pair должен гарантировать, что адреса первого и второго членов отличаются, в то время как это делает его волшебство сжатия пары. Здесь так говорится здесь . Похоже, что это не так, и его поведение отличается на разных компиляторах. Я использую boost v 1.47. Чего мне не хватает?

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\n", &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\n", &same_pair.first(), &same_pair.second());

1 Ответ

7 голосов
/ 08 октября 2011

Когда типы различаются и один или оба типа являются пустым классом, подобъекты должны находиться по одному адресу (если компилятор может отключить пустую оптимизацию базового класса), это точка сжатого пара.

Когда типы совпадают, я думаю, что применяется примечание из главы 10 в стандарте:

Субобъект базового класса может иметь нулевой размер (раздел 9); однако два подобъекты, имеющие одинаковый тип класса и принадлежащие одному и тому же самый производный объект не должен размещаться по одному и тому же адресу (5.10).

Похоже, что именно компилятор должен гарантировать, что они размещены по разным адресам (и VC10 может ошибаться).

Комментарии в заголовке буста указывают, что ранее они вообще не удосужились поместить два разных экземпляра одного и того же пустого класса в сжатую пару. Вместо этого они просто сохранили один экземпляр, и оба first() и second() вернули один и тот же объект.

   // 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).
...