Допустим, у меня есть эти типы:
struct A {
int a;
};
struct B {
int b;
};
struct C : public A, public B {
int c;
};
C*
указатель может быть приведен к A*
указателю без корректировки фактического адреса вообще.Но когда C*
приведен к B*
, значение должно измениться.Я хотел бы убедиться, что два связанных типа, которые у меня есть, могут быть приведены друг к другу без изменения адреса (то есть, что нет множественного наследования или что базовый класс является первой базой производного класса).Это можно проверить во время выполнения, например, так:
assert(size_t(static_cast<A*>((C*)0xF000) == 0xF000);
assert(size_t(static_cast<B*>((C*)0xF000) != 0xF000);
Это работает.Но эта информация известна во время компиляции, поэтому я ищу способ сделать это во время компиляции.Очевидные способы преобразования приведенного выше в статическое утверждение (например, замена assert
на BOOST_STATIC_ASSERT
дает ошибку «приведение к типу, отличному от целочисленного или перечислимого типа, не может появляться в выражении-константе» с g ++ 4.2.
Переносимость не так уж важна. Использование расширений gcc или хакерских хитростей с шаблонами было бы хорошо.
Обновление: Обнаружено, что ранее задавался почти тот же вопрос: C ++, статически определять базовые классы с разными адресами? . Использование offsetof()
также является единственным полезным предложением там.