Здравствуйте, LuciferSaratov, Вы писали:
LS>Я сейчас портирую большую кучу кода из конца 90-х, в которой очень многое завязано на offsetof() на не-POD типах. Код изначально для MSVC 98.
LS>Согласно стандарту это UB, но ведь есть законы, а есть правоприменительная практика.
LS>Как на практике обстоят дела? Мои целевые компиляторы это современный MSVC и clang под x86_64 и ARM.
offsetof использует хак с разыменовыванием нулевого указателя. И получается на виртуальном наследовании это может не работать. Можно попробовать самому реализовать что-то подобное на уже существующем объекте
struct A {
int a;
int b;
};
struct C : virtual A {
int c;
};
#define myoffset(member) template<typename T> size_t offset_of_##member(const T& temp) { return (size_t)((char*)(&(temp.member)) - (char*)&temp); }
myoffset(b)
int main() {
std::cout << offset_of_b(C{});
}
правда меня смущает не будет ли вычитание двух указателей в данном случае UB, но это уже дело десятое. Как минимум, проблемы с offsetof так можно избежать