LINUX.ORG.RU

узнать размер структуры в упакованном виде

 ,


0

1

Доброго всем,

Есть ли какая возможность узнать размер обычной структуры, но в запакованном виде? Своего рода sizeof(struct my_unpacked_struct) , но получить размер как при __attribute__((packed)) , без того чтобы декларировать копию структуры с атрибутом?

Сложи размеры в байтах типов структуры и всё. Считать надо когда бы атрибут выравнивая задаёшь (а тут задаётся выравнивание равное 1ничке ). А тут всё естественно, упакованный размер это тот размер который ты видишь в коде. На деле он другой, но если ты упаковал то просто убрал все выравнивания и всё.

Но калькулировать надо это, ну как всегда учитывая все нюансы конечной железки и всё такое. Я не настоящий сварщик наверняка есть нюансы.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

можно конечно sizeof() каждого члена структуры, но этого перебора кабы и хочется избежать, просто скормить саму структуру, ну или макрос какой нить… хотя можно и в функцию оформить, где будет перебор… Просто может есть уже что-то универсальное вроде sizeof.

paspartu
() автор топика

о получить размер как при __attribute__((packed)) , без того чтобы декларировать копию структуры с атрибутом?

Такой результат можно получить если размер структуры кратен размеру машинного слова которое зависит от разрядности.

Можно посмотреть как компилятор распологает поля в структуре.

Скомпилируй в объектник и натрави на него утиль pahole

(Для gcc рекомендуется ключик "-femit-struct-debug-detailed=any")

Будет видно где есть пустые места между полями.

vel ★★★★★
()
Ответ на: комментарий от paspartu

Ну я вот так придумал раз костыль для костылей. Вместо

struct my_struct_name
{
  char c;
  int  i; 
}

Мы делает так. При объявлении.

structure({
  char c;
  int  i;
},my_struct_name,my_struct_pack_size)

При объявлении через макрос создаём срезу переменную со значением размера упакованной анонимной структуры того же содержания.

#include <stdio.h>

#define structure(structure_body,structure_name,size_name)\
struct structure_name structure_body;\
const size_t size_name = sizeof(struct structure_body __attribute__((packed)));\


structure({
  char c;
  int  i;
},my_struct_name,my_struct_pack_size)


int main(int argc, char *argv[])
{
    printf("nopack=%zu | pack=%zu\n",sizeof(struct my_struct_name),my_struct_pack_size);
    return 0;
}

:D

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Лишняя память на const глобальную переменную может потратиться, линкер может не вычистить. Можно генерить макросом функцию с атрибутом always_inline внутри которой объявляется вариант структуры с атрибутом packed и чтобы эта функция тупо возвращала ее размер. Компилятор такую функцию соптимизирует так, что в месте ее вызова просто подставится размер, и самой «функции» в бинарнике вообще не будет

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

Как-то так:

#include <stdio.h>

#define structure(str_name, str_body, str_var) \
static inline __attribute__((always_inline,const)) size_t str_var() \
{ \
  return sizeof(struct __attribute__((packed)) str_body); \
} \
\
struct str_name \
str_body

structure
(
  my_struct_name,
  {
    char c;
    int  i;
  },

  my_struct_pack_size
);

int main(int argc, char *argv[])
{
    printf("nopack=%zu | pack=%zu\n",sizeof(struct my_struct_name),my_struct_pack_size());
    return 0;
}

SZT ★★★★★
()
Ответ на: комментарий от SZT

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

paspartu
() автор топика