Почему объект класса A
занимает 4 байта?
#include <iostream>
struct F {};
struct D: F {};
struct E: F {};
struct B: D, E {};
struct C: D, E {};
struct A: B, C {};
int main() {
std::cout << sizeof(A{}) << '\n';
}
Правило "оптимизации пустых базовых классов" (empty base optimization) позволяет пустым базовым подобъектам иметь размер 0 в составе объекта-наследника. Однако в то же время два различных базовых подобъекта одного и того же типа обязаны иметь разные адреса, даже если они пусты. У вас в вашей иерархии в классе A
набирается как минимум 4
различных базовых подобъекта типа F
. Это уже требует размера как минимум в 4
минимальных адресуемых единицы памяти.
Если сделать
int main()
{
A a;
std::cout << sizeof a << std::endl;
std::cout << &a << std::endl;
std::cout << (F *)(D *)(B *) &a << std::endl;
std::cout << (F *)(E *)(B *) &a << std::endl;
std::cout << (F *)(D *)(C *) &a << std::endl;
std::cout << (F *)(E *)(C *) &a << std::endl;
}
то получаем (GCC, Clang)
4
0x7ffcc5ed5f5c
0x7ffcc5ed5f5c
0x7ffcc5ed5f5d
0x7ffcc5ed5f5e
0x7ffcc5ed5f5f
MSVC++, похоже, полагает, что для последнего (по порядку в памяти) подобъекта F
нужен лишь уникальный адрес, но не нужно фактического байта памяти, по каковой причине размер A
получается равным 3
. Это нехорошо, ведь какой-то другой - внешний по отношению к A
- объект может разместиться по тому же адресу, что и последнее F
в A
.
Проверим
struct X
{
A a;
char c;
};
int main()
{
X a;
std::cout << sizeof a << std::endl;
std::cout << &a << std::endl;
std::cout << (F *)(D *)(B *) &a.a << std::endl;
std::cout << (F *)(E *)(B *) &a.a << std::endl;
std::cout << (F *)(D *)(C *) &a.a << std::endl;
std::cout << (F *)(E *)(C *) &a.a << std::endl;
std::cout << (void *) &a.c << std::endl;
}
получаем
3
000000B30CEFFA44
000000B30CEFFA44
000000B30CEFFA45
000000B30CEFFA46
000000B30CEFFA47
000000B30CEFFA47
Если я не ошибаюсь, совпадение адресов (F *)(E *)(C *) &a.a
и &a.c
является нарушением требований спецификации языка, т.е. багом в MSVC++.
В C++ стандарте размер структуры должен иметь минимум один байт.
1.8 The C ++ object model
Unless it is a bit-field (9.6), a most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Base class subobjects may have zero size. An object of trivially copyable or standard-layout type (3.9) shall occupy contiguous bytes of storage.
Структура F имеет размер один байт. D = F + 0 = 1 . B = D + E = 1 + 1 = 2 . A = B + C = 2 + 2 = 4 .
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Отвечаю на вопрос, связанный с переобъявлениемВ масштабе вашего кода все нормально
Надо распечатать DataTable(DataGrid) в горизонтальной(альбомной) ориентацииПробовал печатать DataGrid, не влазит(много колонок)
Есть Dictionary < int[], string > example_dictionary , при записи в него новой переменной мне надо проверить, существует ли уже данный ключ, но если делать так: