Однако, присвоение структуре имени в макросе должно будет приводить к другому варнингу - "переопределение имени", так как каждый такой макрос будет раскрываться в повторное определение одной и той же структуры. Это тоже грабли, хотя и вид с боку.
#ifndef ? ... Прикалываюсь - решение другое, но не хочу портить удовольствие от самостоятельного осмысления задачи и ее решения...
Ну будет поуниверсальнее в части большего размера буфера. А всё одно ведь остальной, не показанный нам, хак по доступу к членам этого, с позволения сказать, объекта упрятан в такие-же дефайны, что кстати и подтверждается нагугливанием исходной нетленки по фразе "//размер должен быть степенью двойки: 4,8,16,32...128" - так что ещё и их переписывать придётся - а зачем это вопрошающему?
Pnjom-Penb писал(а):
Прикалываюсь - решение другое, но не хочу портить удовольствие от самостоятельного осмысления задачи и ее решения...
Если компилер не будет ныть на переопределение идентичных по объявлению структур - то и жвачки хватит, чтобы имя на основе параметра сконь-струировать.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Вопрошающему была интересна причина возникновения warning и только, без далеко идущих выводов
Это понятно и, как по мне, весьма похвально с его стороны. Вопрос же мой был больше к предлагающему улучшенную реализацию с предложением оценить трудозатраты на оную доработку.
prinv писал(а):
Мой вопрос фактически был "как правильно описать структуру в хидере?"
Правильность либо неправильность в некоторой мере задаёт и контекст использования. Если моё предположение про глобальную видимость верно - то объявление объекта статическим:
Код:
static FIFO fifo(128);
т.е. видимым только в этом модуле, должно снять претензии копилятора по линковке объектов анонимных структур. Интересно, кстати, отчего он вообще типом озаботился - проект CPP-шный что-ли?
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Мой вопрос фактически был "как правильно описать структуру в хидере?"
Без дефайнов.
Siarzhuk писал(а):
Если компилер не будет ныть на переопределение идентичных по объявлению структур - то и жвачки хватит, чтобы имя на основе параметра сконь-струировать.
С какого потолка взято утверждение, что структуры будут идентичными?
prinv писал(а):
Получаю ошибку "unknown type name 'str_fifo"...
Потому что имя типа здесь не "str_fifo", а "struct str_fifo":
Если компилер не будет ныть на переопределение идентичных по объявлению структур - то и жвачки хватит, чтобы имя на основе параметра сконь-струировать.
С какого потолка взято утверждение, что структуры будут идентичными?
"Жвачка" в данном случае - препроцессорная конкатенация корня имени структуры с параметром-размером, позволяющая сделать разные имена структур для разных размеров буфера. Для одинаковых размеров - структуры будут идентичны:
Siarzhuk: Если компилер не будет ныть на переопределение идентичных по объявлению структур ... Pnjom-Penb: С какого потолка взято утверждение, что структуры будут идентичными? Siarzhuk: "Жвачка" в данном случае - препроцессорная конкатенация ...
Вы не на тот вопрос отвечаете - структуры НЕИДЕНТИЧНЫ! Потому и был задан вопрос - с чего это они представляются Вам идентичными, да еще с упором на некую очевидность этого...
И, кстати, ...
Siarzhuk писал(а):
Pnjom-Penb писал(а):
должно было выглядеть так:
Код:
[...] unsigned char *tail;\ [...]
Ну будет поуниверсальнее в части большего размера буфера.
... разница между объявлением указателей head и tail как "unsigned char" или как "unsigned char*" заключается вовсе не в бОльшем размере, который смогут обслуживать вторые, а в арифметике - арифметика указателей отличается от арифметики объектов, и объявлять указатели, как "unsigned char" - это те еще грабли.
Вы не на тот вопрос отвечаете - структуры НЕИДЕНТИЧНЫ!
т.е.
Код:
struct s1 { char buf[13]; };
struct s2 { char buf[13]; };
не идентичны? И в чём же разница, позвольте спросить?
Pnjom-Penb писал(а):
объявлять указатели, как "unsigned char" - это те еще грабли.
Вы в "источник вдохновения" откуда исходный дефайн был взят вообще заглядывали? Там указателями совсем не пахнет. Да даже и без этого очевидно-же - буфер и индексы.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Вы в "источник вдохновения" откуда исходный дефайн был взят вообще заглядывали? Там указателями совсем не пахнет.
Согласен, привычка давать имена "head/tail" именно указателям сыграла со мной шутку и я приписал ТСу свой ход мыслей. А Ваши рассуждения о "большей универсальности в смысле размера" еще и укрепили меня в моей ошибке.
Если уж заговорили об источниках вдохновения, то хотелось бы узнать и об источнике Вашего тоже... Итак, Вы предложили ТСу модификацию его макроса, "обезьянничающую" (mangling) имя структуры, приклеивая к ней размер массива, переданный, как параметр "struct fifo##__size ... fifo10; ... fifo11; ..."
В связи с этим, к источнику такого вдохновения возникают следующие вопросы: 1. Как так получилось, что для одного и того же размера (13) этот способ породил разные имена структур? Цитата:
Siarzhuk писал(а):
struct s1 ... struct s2 ... не идетичны?
2. Что делать ТСу, когда он, вызвав такой макрос дважды, с одинаковым параметром-размером, получит "те же яйца, только в профиль"? Вроде хотели уйти от повторяющихся объявлений, а пришли к ним же... Сильный ход! 3. Если компилятор в такой ситуации "не будет ныть", то получится, что программист будет думать, что завел две такие FIF'ы, а физически все обращения пойдут в одну!.. Как правильно назвать такие грабли - "граблища", или уж сразу "мастдайка"?
1. Как так получилось, что для одного и того же размера (13) этот способ породил разные имена структур?
Это я вас методом "от противного" подловить хотел. В реальности, как вы совершенно правильно заметили, тут как раз тот случай когда конкатенирующий манглинг не сработает - из чего я собственно и начал мечтать-размышлять вслух про идентичные структуры с одинаковым именем - мол мы объявляем тип, и тип этот бинарно идентичен предыдущему объявлению структуры с таким-же именем, и почему-бы компилятору не увидеть этот факт и не понять что это один и тот-же тип, мечты, мечты.... А вот, кстати, конкатенирование к имени структуры ещё и __LINE__ нас не спасёт?.
2. Что делать ТСу, когда он, вызвав такой макрос дважды, с одинаковым параметром-размером, получит ...
Я бы в одной строке объявил: FIFO(128) fifo1, fifo2, fifo3;
Pnjom-Penb писал(а):
получится, что программист будет думать, что завел две такие FIF'ы, а физически все обращения пойдут в одну!
Не, там же под дефайном только определение типа спрятано (на CPP-шные шаблоны смахивает, кстати) - а переменные (инстансы) мы уже сами в коде задаём разные - т.е. и работать мы будем с двумя разными переменными. Или вы не это имели ввиду?
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Не, этого сайта не знаю. Первое, что бросилось в глаза - "Что бы использовать этот код для fifo c размером 256 и более, надо для head и tail поменять тип c unsigned char на unsigned short" - это утверждение платформеннозависимое. Писать такое "тихо, сам с собою" - некоторое время можно (недолго), а распространять такую заразу массово - нехорошо. Если важна интерпретация содержания переменной, то в ход идут типы, предназначенные для соотв-го содержимого, если же важен именно ее размер, то необходимо и типы выбирать те, что задают размер (uint8_t, uint16_t).
Siarzhuk писал(а):
Это я вас методом "от противного" подловить хотел.
Не стоит никого подлавливать, тем более, что ТС от этого только еще больше запутается. А он и сам уже многое для этого сделал.
Siarzhuk писал(а):
А вот, кстати, конкатенирование к имени структуры ещё и __LINE__ нас не спасёт?. Вроде ешё и __COUNTER__, помню, имеется.
У ТСа (Prinv) полный каквардак в голове как по поводу синтаксиса/семантики языка, так и в отношении работы препроцессора. Пытаясь "автоматизировать", а по-сути - спрятать от своих глаз, создание типа, он умножает один кавардак на другой и получает уже не два кавардака, а кавардак в квадрате... а Вы подбираете способ, как ему из этой ситуации не выкарабкаться? Я, со своей стороны, ему посоветовал - без дефайнов! Пусть все будет прозрачно, для начинающих это важно.
Первое, что бросилось в глаза - "Что бы использовать этот код для fifo c размером 256 и более, надо для head и tail поменять тип c unsigned char на unsigned short" - это утверждение платформеннозависимое.
Вот-вот, я ваш "переход на указатели" в этом ключе и расценил - как избавление от ограничений размера переменной индекса переходом на прямую адресацию хвоста и головы. Другой вопрос, что это дезавуирует все остальные трюки из этого заголовка которые заточены именно под индексы - ну то дело для препроцессора обычное - чем больше прячется под #define тем более снижается универсальность и безопасность применения такого дефайна.
Pnjom-Penb писал(а):
Пытаясь "автоматизировать", а по-сути - спрятать от своих глаз, создание типа, он умножает один кавардак на другой и получает уже не два кавардака, а кавардак в квадрате...
Судя по последним его отметкам в теме, движение как раз в правильном направлении - взято чужое решение на препроцессоре и приведено к читабельному C коду. Впрочем, надеюсь, он нам и сам расскажет, что получилось.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 33
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения