LINUX.ORG.RU

Аналог шаблонов для языка С.

 ,


0

3

Доброго времени суток!

Столкнулся с проблемой написания структуры с переменной длиной поля. На С++ код пишется элементарно и выглядит как:

template <uint8_t len> struct TPack{
	char Length=len;
	char Item[2];
	char Value[len];
};

Не спорю, что можно бы выделить под Value аж 256 байт, коих с головой хватит под нужную строку, но это требуется для того, чтобы максимально снизить количество передаваемой информации. И не объявлять же под каждую передаваемую связку Item-Value новую структуру нужного размера (Хотя с точки зрения компилятора С++, каждое новое использование шаблона именно это и подразумевает)!

Может, в сях есть уже готовые структуры подобного вида, но мне они не известны.

★★

Выделяй память нужного размера отдельно и храни в структуре указатель на неё.

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

Ну это директива препроцессора. Если я работаю с динамической памятью (размер Value вычисляется в ходе выполнения программы), то таким образом мне не выделить память.

aido ★★ ()
Ответ на: комментарий от Vovka-Korovka

Точно. совсем забыл про массивы нулевой длины.

aido ★★ ()

чтобы максимально снизить количество передаваемой информации.

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

В рантайме это делается это так:

typedef struct {
  uint64_t len;
  char data[0];
} str_t;

И не объявлять же под каждую передаваемую связку Item-Value новую структуру нужного размера!

Дак ты в своей портянке тоже самое и делаешь. Не?

Может, в сях есть уже готовые структуры подобного вида, но мне они не известны.

Твоя портянка абсолютно не имеет смысла и не отличается от дефолтной строки.

Если у тебя длинна определяется не в рантайме, то нахрен твоя структура вообще нужна? Если же она определяется в рантайме, то твоя портянка просто не работает.

anonymous ()
Ответ на: комментарий от aido

то таким образом мне не выделить память.

Твоя портянка на шаблонах итак её никак не выделит.

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

Ага. А если надо набор си-строк передать, каждая из которых относится к своему контексту Item, то будем мы угадывать, что же мы такое приняли, не имея итемов.

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

Типичный предстовитель хомо-дебилиус, который вместо того, чтобы мести улицу спорит со мною.

И как всегда хомо-дебилиус не удасужился ответить на все вопросы.

Ну давай я так и быть, покажу где твоё место:

Мой ответ был вот на этот высер:

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

Т.е. никаких итемов тут нет.

Далее:

template <uint8_t len> struct TPack{
	char Length=len;
	char Item[2];
	char Value[len];
};

С чем же у нас связано value - дак ба, только с len; А где же итемы?

Т.е. пацан решил запилить паскалик-строку, которая никак не может быть компактней си-строки, она может быть при случае <256 равнокомпактной.

что же мы такое приняли, не имея итемов

Ну и фиерический осёр с итемамами, а где же, уважаемый балабол, вы нашли в моём сообщение «выкидываем итемы»?

Ну и контрольный - а что собственно мешает засунуть в строку твои днище-итемы? А раз ничего и об этом я ничего не говорит - ты убогий балабол, получается так?

anonymous ()
Ответ на: комментарий от aido

Можно подумать, плюсеры не так делают! Хочешь в стиле плюсов, делай макрос вроде

#define Tpack(len, structname)  typedef struct{ \
	char Length=len; \
	char Item[2];    \
	char Value[len]; \
} structname;
Хочешь по-человечески — пиши конструктор:
typedef struct{ 
	char Length; 
	char Item[2];    
	char *Value; 
} Packed;

Packed* new_Packed(char L){
   Packed *r = malloc(sizeof(Packed));
   r->Length = L;
   r->Value = malloc(L);
   return r;
}

void delete_Packed(Packed **p){
   free(*packed->Value);
   free(*p);
   *p = NULL;
}
Только объясни, в чем прикол размер в чарах измерять?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em
  1. Тут у тебя 2 malloc'а вместо одного.
  2. Packed можно выделять только на куче, на стеке/в массиве/внутри другой структуры не выйдет - только указатели хранить.
Begemoth ★★★★★ ()
Ответ на: комментарий от Eddy_Em

Эдик - это делается не так.

Это делается так:

typedef struct {
  uint64_t len;
  char data[0];
} str_t;


str_t * alloc_str(char * s, uint64_t len) {
  str_t * str = malloc(sizeof(str_t) + len);
  str->len = len;
  memcpy(str->data, s, len);
  return str;
}

Только объясни, в чем прикол размер в чарах измерять?

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

Ну вернее эти изваяния изначально фиерическое говно, но типа абстрактно какбэ компактно.

anonymous ()
Ответ на: комментарий от Begemoth

Packed можно выделять только на куче

И почему уже?

на стеке

Что же этому помешает?

в массиве

Бесполезно. Крестовое поделие в массив тоже не может. Да и не имеет смысла.

внутри другой структуры не выйдет

Так же бесполезно. Пацан рассуждал о рантайме.

Какой жопой рантайм динамика может как-то храниться в в каком-то статитеском типе? Изначальная идея пацана фиерический бред.

Я уж не говорю об обходе этой куллстори, т.е. его набора шаблонных структурок.

anonymous ()

Попробовать структуру в макрос запихать, что-то по типу:

#define STRUCT(a,b) struct a{\
char s1[a];\
char s2[b];\
};

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

И почему уже?

Потому что «конструктор» такой. Ах, да я же забыл, в С неинициализированные и недоинициализированные объекты - это нормально.

Что же этому помешает?

То же самое.

Бесполезно. Крестовое поделие в массив тоже не может.

Это с фига ли?

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

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

Правда-правда ^_^

anonymous ()
Ответ на: комментарий от Begemoth

Потому что «конструктор» такой.

Как же фиерично ты обосрался.

Ах, да я же забыл, в С неинициализированные и недоинициализированные объекты - это нормально.

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

То же самое.

И конечно же балаболка причину не назвала.

Это с фига ли?

С того, что это не возможно, ибо длинна типов не фиксирована. Но ты можешь попытаться и опять же обосраться.

Откуда вы, нули ничтожные берётесь. Ну обосрался - заткнись и не кукарекай мне тут, но нет же - нулёвая балаболка продолжает мне кукарекать, дак ладно кукарекать - оно мне задвигает свои сектанские куллстори. Мне насрать на твою веру. Смекаешь?

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

Пшла нахрен, мразь. Меня не интересуют возгласы нулёвого, ничтожного мусора.

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

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

Опять мразь эмулирует что-то своим шизоидным бредом.

Но давай, говно, я опять тебе твоей убогой роже мокну в твоё же говно, хотя макать говно в говно.

Ты мне выкатываешь мою цитатку, где я писал:

модераторы все поудаляли
труды больше никто не увидит
написал десятки работающих программ

Типичное убогая балаболящая мразь. Зову свою собачку - она за тобою гвоно подотрёт.

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

Хотя, судя по косвенным признакам ты и являешься той подстилкой.

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

Ты мне выкатываешь мою цитатку, где я писал:
модераторы все поудаляли
труды больше никто не увидит
написал десятки работающих программ

То, что работает и решает поставленную задачу я уже сотни раз писал. Но ты бдишь, чтобы оно своевременно удалялось с лора, а иначе как же ты сможешь продолжать врать?
TrueTsarCPP (29.08.2015 23:44:16)

Т.е. алгоритм действий следующий - мы выпиливаем весь код и пруфцы царя с лора, потом везде постим, что у царя кода и пруфцов нет( в каждой теме), а так же, что царь везде обосрался
anonymous (29.08.2015 15:50:43)

Ты мне лучше объясни - почему сектанты-модераторы трут все мои комменты с кодом, с моим уничтожением лалок и прочим, а с лютый оффтом и мусор не трут.
anonymous (27.08.2015 18:07:11)

Тебе не надоело? Тут чуть ли не каждый тред наполнен твоими виляниями жопой и тихим сливом в конце.

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

Сейчас царь ответит что-то в духе: ага, я-то говорил про сотни, а ты сказал десятки - абасали балаболку, аззазазазаза!"

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

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

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

Чета царь надоел. Он, похоже, реально болен. Тут как минимум уже ярко выраженная паранойя. Типа у царя в своем воображаемом мирке написаны тонны кода, слиты сотни лалок и толпы поклонников, но действует некая секта, которая все это удаляет, скрывает цареву ениальность и уводит от него фанатов.

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

Это единственное, чем он тебе надоел?

anonymous ()

И не объявлять же под каждую передаваемую связку Item-Value новую структуру нужного размера

Макросом делай тип через анонимную структуру.

#include <stdio.h>
#include <inttypes.h>
#define MK_AR(len) struct {uint8_t Length; char Item[2]; char Value[len];}

int main(void)
{
  MK_AR(5) a = {3, {1,2}, {1,2,3}};
  printf("{{%u}, {%i, %i}, {%i, %i, %i}}\n", a.Length, a.Item[0], a.Item[1], a.Value[0], a.Value[1], a.Value[2]);
  return 0;
}
SZT ★★★★★ ()
Ответ на: комментарий от anonymous

У этой хрени

typedef struct {
  uint64_t len;
  char data[0];
} str_t;
будет неправильный sizeof. Размер подобной структуры придется определять через len + sizeof (хотя тут есть свои подводные камни, если там data не char то надо делать #pragma pack еще, фиг знает как там компилятор эту структуру упакует). И если такую структуру попробовать передать по значению в функцию, это не будет нормально работать.

К тому же массивы нулевой длины это gcc extension https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

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

Передать по сети (типа медленному каналу)? Дык выделяйте память с запасом, а передавайте только содержательную часть.

AIv ★★★★★ ()
Ответ на: это gcc extension от next_time

Насчет gcc extension - это относится к char data[0]. К flexible array member это не относится, но проблема с sizeof() и с невозможностью легко передать такую структуру в функцию по значению остается.

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

И конечно же балаболка причину не назвала.

Буду благодарен, если покажешь, как в Си положить объект динамически определяемой длины на стек. Если, например, есть функция, которая первым аргументом принимает длину, вторым — данные в виде строки. Как эту строку положить на стек?

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

будет неправильный sizeof

Это с какого бадуна? Он правильный.

Размер подобной структуры придется определять через len + sizeof

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

Все размеры там рантайм - это голова, которая позволяет получить просто получить адрес следующий за len. К чему ты приплёл всё эти убогие днищерассуждения мне не ясно.

(хотя тут есть свои подводные камни, если там data не char то надо делать #pragma pack еще, фиг знает как там компилятор эту структуру упакует)

Не надо. Если ты не знаешь - это не говорит о том, что никто не знают.

Какой бы тип базовый тип ты сюда не засунул - никаких днищепаков тут делать не надо. И ты бы это знал, если бы понимал, что выравненный uint64_t всегда оканчивается+1 выравненным по 1/2/4/8 байтам адресу.

если такую структуру попробовать передать по значению в функцию, это не будет нормально работать.

Это будет работать так, как задумывалось. Это просто не имеет смысла. А твои горерассуждения никого не интересуют. Если сувать жопу в рукава тоже ничего не выйдет.

Если ты так уж боишься, то тебе ничего не мешает засунуть в тайпдеф указатель(я так и хотел изначально сделать, но ладно).

К тому же массивы нулевой длины это gcc extension https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

Нет. Это есть и в убогих днищестандартах.

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

К flexible array member это не относится

Как мило переобулся.

но проблема с sizeof() и с невозможностью легко передать такую структуру в функцию по значению остается.

Проблемы никакой не существует. Сайзоф для рантайм динамики не работает итак.

Предавать по значению эту структуру не имеет смысла, от слова «никакого». Она никогда не используется - это обёртка над:

len = *(uint64_t *)data, str = data + 8;

Когда ты опишешь реальный смысл передавать её по значению, где это не будет логической ошибкой - тогда рассуждать можешь, так же, как и с сайзофом в рантайме.

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

С того, что это не возможно, ибо длинна типов не фиксирована.

Чото царь совсем уже засливался.

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

Взглянем на типичного балабола - балабол всегда врёт и меняет понятия, ибо весь его высер убогое говно.

Балаболу была задана конкретная задача - предоставить цитату, включающую:

написал десятки работающих программ

Т.е. конкретное определение «работающих программ». Ведь ламерок именно так и написал, не код, не портянки, ни чего-либо ещё. Ибо тот час бы обделался. Он высрал убогое, никак не определяемое понятие. «работающих программ».

модераторы все поудаляли

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

труды больше никто не увидит

И так же, что труды мои больше никто не увидит.

Что же мы видим:

То, что работает и решает поставленную задачу я уже сотни раз писал. Но ты бдишь, чтобы оно своевременно удалялось с лора, а иначе как же ты сможешь продолжать врать?

Ищем слова «всё удалали», «работающих программ», «труды больше никто не увидит» - найдено ноль.

Обосрался.

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

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

Никаких «никто не увидел» и «работающих программ» тут нет. Точно так же, как и утверждения «всё удаляют».

Обосрался.

Ты мне лучше объясни - почему сектанты-модераторы трут все мои комменты с кодом, с моим уничтожением лалок и прочим, а с лютый оффтом и мусор не трут.

Опять же, никаких «никто не увидел» и «работающих программ» тут нет.

Нужно слово «всё» относительно «работающих программ», либо просто «всё» - т.е. обсёр.

Далее, удаление постов с кодом - это конкретный факт - даже далеко ходить не надо. Все посты с кодом у царя1с77 выпилили. Конкретные пруфцы - недавняя тема с ммапом. Там ещё где-то я постил код - тоже выпилили.

Это выпилили, потом когда я об этом сказал - снесли все мои комменты в той теме, чтобы сокрыть свой обсёр.

Удаляется весь код, который я пощу от регистрантов. Не трогаются только некоторые мои темы, которые разрослись. И то половина там выпилена.

Это нотариально заверенный факт.

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

Вперёд - высри, а я опять тебя смешаю с говном. Ты мне уже год обещаешь показать как меня катают во всех темах. Вперёд. Ты там обещал 3штуки с пояснениями.

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

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

Вся суть, ублюдище просто не палится. Прям балаболка срёт тем, о чём мечтает.

Ведь именно в подтирание «концов» и есть основа алгоритма сектантов, который я описал.

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

Чета царь надоел. Он, похоже, реально болен. Тут как минимум уже ярко выраженная паранойя.

О, дак я уже вижу типичные аутистические методички.

Как любая другая секта - секта это ты, некомпетентый балабол с админкой и боярин, которому ты пытаешься подражать, либо твой собрат по секте.

Основа любой секты - это выставлять себя легионом и все свои высеры сводить к «воле народа». Т.е. вы, пара аутистов пытаетесь всех убедить, что весь лор против царя - типичная ситауция.

Потом, когда сектантов начинаешь выводить на чистую воду - они начинают придумывать тысячи отговорок, а «паранойя» и доведение до абсурда с убогим враньём и подменой понятий. Всё это, нацеленно на ту же задачу - убедить, что против пациента легион.

Типа у царя в своем воображаемом мирке написаны тонны кода, слиты сотни лалок и толпы поклонников, но действует некая секта, которая все это удаляет, скрывает цареву ениальность и уводит от него фанатов.

Вот, типичный пример вранья и доведения до абсурда. Время идёт, а методички не меняются.

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

Типичные методички тусы хомячков. Просто убого.

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

Ржали всем стартапом. Давай еще, на бис.

Уже много чего интересного показывал - я не исполнитель, мне вредно и не интересно заниматься всякой хернёй бесполезной. Я создаю подходы и решаю проблемы. Я теоретик, только в отличии от рядовых бомжей я эти занялся уже после того, как осилил пиление на уровне царя.
TrueTsar1C77 (10.08.2015 19:46:03)

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

Какой бы тип базовый тип ты сюда не засунул - никаких днищепаков тут делать не надо. И ты бы это знал, если бы понимал, что выравненный uint64_t всегда оканчивается+1 выравненным по 1/2/4/8 байтам адресу.

http://www.x86-64.org/documentation/abi.pdf страница 13, тип long double

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
  struct {uint64_t len; long double Arr[1];} test = {1,{66.666}};
  printf("%p %p %td\n", &(test.len), test.Arr, (char *)test.Arr-(char *)&(test.len));
  return 0;
}

$ gcc -m32 test.c
$ ./a.out
0xffb4c54c 0xffb4c554 8
$ gcc -m64 test_FFF2.c
$ ./a.out 
0x7fff19577230 0x7fff19577240 16

И в качестве длины вполне может использоваться какой-нибудь uint8_t

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

как в Си положить объект динамически определяемой длины на стек

alloca?

alloca это не очень хорошо. Если вызывать alloca внутри цикла, на каждую итерацию оно будет выжирать память из стека. Лучше использовать VLA

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

Зачем ты что-то пытаешься, весь твои попытки тщетны и будут помножены на ноль. Специально для таких экспертов - я там сделал 3 уточнение про базовые типы, чтобы мне адепты не высрали структурки, а так же специальное уточнение, что бы не высрали всякие малоюзабельные лонгдаблы и прочие int128 куллстори:

оканчивается+1 выравненным по 1/2/4/8 байтам адресу.
тип long double

Заблаговременно эксперт был помножен на ноль, но ладно, авось ты не заметил.

И в качестве длины вполне может использоваться какой-нибудь uint8_t

И опять же жалкие попытки, и опять же я заблаговременно помножил эксперта на ноль, уточнением, что говориться только об uint64_t.

gcc -m32

Меня мусор не интересует. Хотя тут не фортануло - зачем ты это запостил?

Т.е. не относящиеся к моему утверждению высеры меня не интересуют, и были помножены на ноль заранее. Ну и, чего ты добился?

Ты мне лучше отвечай на мои вопросы, а не пытайся меня на чём-то поймать.

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

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

Лучше использовать VLA

Не позваляют высрать однострочник. Когда запилят (char[len]){} - тогда будет альтернативой.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.