Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 05.05.19 15:03
Оценка:
Есть ли способ указать, чтобы компилятор не вставлял выравнивание во внешнем объекте ?

struct A { int i; };

struct B { A a; };

struct C { A a; int i; };


Есть ли способ указать, чтобы после 'a' гарантированно не было выравнивания в классах B и C?
Желательно без изменений этих классов.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Гарантировать размер объекта в агрегации
От: ononim  
Дата: 05.05.19 15:16
Оценка:
_NN>Есть ли способ указать, чтобы после 'a' гарантированно не было выравнивания в классах B и C?
_NN>Желательно без изменений этих классов.
Добавление __attribute__((__packed__)) считается изменением класса?
Как много веселых ребят, и все делают велосипед...
Re[2]: Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 05.05.19 18:49
Оценка:
Здравствуйте, ononim, Вы писали:

_NN>>Есть ли способ указать, чтобы после 'a' гарантированно не было выравнивания в классах B и C?

_NN>>Желательно без изменений этих классов.
O>Добавление __attribute__((__packed__)) считается изменением класса?
Классу A можно добавлять что угодно.
А если есть ещё и стандартное решение будет совсем круто.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Гарантировать размер объекта в агрегации
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.05.19 19:49
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли способ указать, чтобы компилятор не вставлял выравнивание во внешнем объекте ?


Стандартного (т.е., описанного в каком-либо стандарте) решения нет, но многие компиляторы понимают #pragma pack (1) или #pragma pack (push, 1)/#pragma pack (pop)
Re[2]: Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 06.05.19 04:29
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, _NN_, Вы писали:


_NN>>Есть ли способ указать, чтобы компилятор не вставлял выравнивание во внешнем объекте ?


Pzz>Стандартного (т.е., описанного в каком-либо стандарте) решения нет, но многие компиляторы понимают #pragma pack (1) или #pragma pack (push, 1)/#pragma pack (pop)

Проблема в том, что это надо делать для B и C и любого класса который имеет члена типа A, а я хочу чтобы не нужно было это повторять
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Гарантировать размер объекта в агрегации
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 06.05.19 04:50
Оценка: +3
Здравствуйте, _NN_, Вы писали:

Pzz>>Стандартного (т.е., описанного в каком-либо стандарте) решения нет, но многие компиляторы понимают #pragma pack (1) или #pragma pack (push, 1)/#pragma pack (pop)

_NN>Проблема в том, что это надо делать для B и C и любого класса который имеет члена типа A, а я хочу чтобы не нужно было это повторять

Но это единственный доступный способ
Если цель серриализация, то как мне кажется, лучше использовать что-то типа Protobuf, нежели с выравниванием заморачиваться.
Re[4]: Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 06.05.19 07:02
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Здравствуйте, _NN_, Вы писали:


Pzz>>>Стандартного (т.е., описанного в каком-либо стандарте) решения нет, но многие компиляторы понимают #pragma pack (1) или #pragma pack (push, 1)/#pragma pack (pop)

_NN>>Проблема в том, что это надо делать для B и C и любого класса который имеет члена типа A, а я хочу чтобы не нужно было это повторять

KP>Но это единственный доступный способ

KP>Если цель серриализация, то как мне кажется, лучше использовать что-то типа Protobuf, нежели с выравниванием заморачиваться.

Цель улучшить язык
Есть много типов, для которых хотелось бы гарантировать размер, скажем: unique_ptr, array и т.д.
Хочется иметь гарантию, что замена указателя на unqiue_ptr или массива на std::array не отразиться на размере типа.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Гарантировать размер объекта в агрегации
От: rg45 СССР  
Дата: 06.05.19 08:28
Оценка: :))) :)
Здравствуйте, _NN_, Вы писали:

_NN>Цель улучшить язык


Да признайся уже, реинтерпреткастишь? Мы поймем и простим
--
Re[3]: Гарантировать размер объекта в агрегации
От: AleksandrN Россия  
Дата: 06.05.19 10:01
Оценка:
Здравствуйте, _NN_, Вы писали:

Pzz>>Стандартного (т.е., описанного в каком-либо стандарте) решения нет, но многие компиляторы понимают #pragma pack (1) или #pragma pack (push, 1)/#pragma pack (pop)

_NN>Проблема в том, что это надо делать для B и C и любого класса который имеет члена типа A, а я хочу чтобы не нужно было это повторять

Посмотри опции компилятора. У GCC есть опция -fpack-struct[=n] . У других компиляторов, вроде бы, тоже есть параметры, что бы задать выравнивание. Если задано выравнивание и опцией сборки и #pragma pack, то используется #pragma pack.
Re[6]: Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 06.05.19 11:10
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, _NN_, Вы писали:


_NN>>Цель улучшить язык


R>Да признайся уже, реинтерпреткастишь? Мы поймем и простим

Как раз он не при чём.
Скажем есть у меня:
template<typename T, size_t N> struct array { T elems[N]; };


Используется просто:
class X
{
 array<int, 10> a;
};


Я бы хотел, чтобы компилятор гарантировано интерпретировал его как:
class X
{
  int a[10];
  // выравнивание класса X
};


Сейчас теоретически это выглядит так:

class X
{
  int a[10]; 
  // внутреннее выравнивание array<int, 10>
  // выравнивание класса X
};
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Гарантировать размер объекта в агрегации
От: rg45 СССР  
Дата: 06.05.19 11:15
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Скажем есть у меня:

_NN>Используется просто:
_NN>Я бы хотел, чтобы компилятор гарантировано интерпретировал его как:
_NN>
_NN>class X
_NN>{
_NN>  int a[10];
_NN>  // выравнивание класса X
_NN>};
_NN>


Да цель твоя понятна. Не понятно, почему это так важно для тебя.
--
Re[3]: Гарантировать размер объекта в агрегации
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.05.19 11:22
Оценка:
Здравствуйте, _NN_, Вы писали:

Pzz>>Стандартного (т.е., описанного в каком-либо стандарте) решения нет, но многие компиляторы понимают #pragma pack (1) или #pragma pack (push, 1)/#pragma pack (pop)

_NN>Проблема в том, что это надо делать для B и C и любого класса который имеет члена типа A, а я хочу чтобы не нужно было это повторять

Опыт показывает, что если набивать структуры аккуратно, расставляя 2/4/8-байтовые типы по правильно выровненным позициям (и добавляя по мере необходимости явные поля для заполнения дыр) можно добиться того, что компилятор не будет трогать выравнивание. При этом лучше использовать типы навроде uint32_t или int64_t, а не int и long.
Re[8]: Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 06.05.19 12:44
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, _NN_, Вы писали:


_NN>>Скажем есть у меня:

_NN>>Используется просто:
_NN>>Я бы хотел, чтобы компилятор гарантировано интерпретировал его как:
_NN>>
_NN>>class X
_NN>>{
_NN>>  int a[10];
_NN>>  // выравнивание класса X
_NN>>};
_NN>>


R>Да цель твоя понятна. Не понятно, почему это так важно для тебя.


Ну как почему, производительность

Например я делаю обёртку для ссылки, чтобы класс стал некопируемым и я хочу, чтобы это не влияло на размер класса.
Можно конечно в сам класс добавлять необходимые функции явно, но хочется удобства.

struct A
{
 A(int& i):i(i) {}

 int& i;

 // неявно копируется
};

template<typename T>
struct non_copyable_ref
{
 non_copyable_ref(T& value):value(value) {}

 non_copyable_ref(non_copyable_ref const&) = delete;
 non_copyable_ref& operator=(non_copyable_ref const&) = delete;

 T& value;
};


struct B
{
 B(int& i):i(i) {}

 non_copyable_ref<int> i;

 // неявно не копируется
};

int main()
{
 int i;
 A a1(i);
 A a2(a1);
 
 B b1(i);
 B b2(b1); // Error
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Гарантировать размер объекта в агрегации
От: IID Россия  
Дата: 08.05.19 13:51
Оценка: 9 (1) +1 :)
Здравствуйте, _NN_, Вы писали:

R>>Да цель твоя понятна. Не понятно, почему это так важно для тебя.


_NN>Ну как почему, производительность


Производительность при нарушении выравнивания ? Оригинально-с!

Более того, есть архитектуры, которые принципиально не умеют обращаться к невыровненным данным. ARM например.
Интел тоже умеет генерировать исключение при невыровненном доступе. Но рукожопов слишком много, так и не взлетело.
kalsarikännit
Re[10]: Гарантировать размер объекта в агрегации
От: _NN_ www.nemerleweb.com
Дата: 08.05.19 14:45
Оценка:
Здравствуйте, IID, Вы писали:

IID>Производительность при нарушении выравнивания ? Оригинально-с!

Проблема не с выравниванием, а с размером объекта.
Я хочу иметь гарантии, что мой объект будет располагаться также как если бы я скопировал все члены класса во внешний класс.

Т.е.
[[какой-нибудь-атрибут]]
class A { int* p; int x; };

class B { A a; int y; };

// Гарантировано будет расположен в памяти как
class B { int* p; int x; int y; };

// , а не как позволительно компилятора вроде
class B { int* p; int x; int padding_after_a; int y; };
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.