2016-10-02 1 views
0

Я ищу способ, чтобы получить Orginal размер STRUCT/класс до того, как компилятор выровнен его (более четко скажем, сумму полей членов структуры/класса), как это:Возможно ли получить исходный размер класса/структуры до того, как компилятор выровняет его?

struct Foo{ 
    char c; 
    // the compiler will appen 3 bytes here 
    int i; 
}; 

Sizeof (Foo) возвращает 8, но размер оригинала равен 5.

предположит, что мы хотим, чтобы написать шаблон функцию или макрос с именем orig_sizeof()

template <class t> 
size_t orig_sizeof(t) 
{ 
    // calculate the sum of the fields of t 
} 

Конечно sizeof внутренний макрос, ключевым словом макрос, который не имеет исходный кода.

Возможный способ, чтобы это путем изменения структуры ALIGMENT с использованием __attribute__ или #pragma, чем получить размер с помощью SizeOf после этого resturing в ALIGMENT по умолчанию (может быть, C++ 11 в decltype может быть полезно!), Любые идеи о полезное внедрение?

Edit: им пытаются написать оптимизированную библиотеку, которая не принимает в качестве аргумента в не оптимизированной структуры/класса, путем сравнения SizeOf (тип) с orig_sizeof (типа), и запрашивает у пользователя перестроить feilds для более высокая производительность, если возможно

+1

Нет, его не по ssible. –

+2

1) Не используйте спам-теги. C не C++ не C.2) Почему, по вашему мнению, размер объекта изменяется с выравниванием? 3) Если 'sizeof (Foo) == 8', размер' Foo' ** равен ** '8'. – Olaf

+2

Нет такого понятия, как «оригинальный размер». У вас просто неправильный образ системы типа C++. –

ответ

0

Вы могли бы определить структуры в отдельном заголовке с условной компиляции для упаковки:

struct 
#ifdef pack 
__attribute__((packed)) 
PackedFoo 
#else 
Foo 
#endif 
{ 
    char c; 
    int i; 
}; 

Затем с помощью препроцессора, чтобы включить упакованный и распакованный вариант структуры:

#include "foo.hpp" 
#define pack 
#include "foo.hpp" 

Это было позволяют наблюдать два размера, как если бы они были одного и того же типа:

//custom sizeof for packed representation 
#define sizeof_packed(type) sizeof(Packed##type) 

int main(){ 

    std::cout << sizeof(Foo) << '\n';  //prints 8 
    std::cout << sizeof_packed(Foo) << '\n'; //prints 5 
} 
+0

там мы идем! метапрограммирование <3 –

0

№ C++ не предлагает эту функциональность. В будущем, когда одно из многих предложений по размышлению войдет в Стандарт, вы сможете получить размеры всех членов. Однако это бессмысленно, и делать то, что вы хотите, невозможно. Вот почему:

1) В вашем примере struct {char; int; }; всегда будет длиной 8 байтов, независимо от порядка членов. всегда будет 3 байта заполнения: либо между char и int, в конце, 1 между int и char и 2 в конце ... Невозможно построить «эффектно упакованную» структуру с использованием стандартного C++.

2) Наследование. Компилятор может повторно использовать дополнение в родительских структурах для дочерних элементов. Подпунктом этого является «Пустая базовая оптимизация», которая может сделать размер всего объекта меньше суммы его оснований и членов. Или нет. EBO не является обязательным. Получайте удовольствие, пытаясь определить, был ли EBO просто не вызван, а структура «эффективно упакована», или она была запущена, и у вас есть 2 бродячих байта где-нибудь.

3) Динамические возможности отправки. Обычно это еще один невидимый элемент-указатель (или несколько в случае множественного наследования) в вашем классе, который добавит к нему свои собственные требования к элек- трированию. Тогда применяется (1). Что еще хуже, вы не можете изменить, где будут размещаться эти указатели.

Смежные вопросы