ViKo 1 7 июня, 2020 Опубликовано 7 июня, 2020 · Жалоба x893, я использую в данном проекте C99, поскольку передаю другому лицу. const меня от создания самих массивов, структуры не спасёт. А если typedef задать и для массивов пикселей символов, и для структуры? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 7 июня, 2020 Опубликовано 7 июня, 2020 · Жалоба 10 часов назад, ViKo сказал: Отдельно имеется массив смещений для каждого массива строк символов из структуры. К адресу структуры прибавляется смещение, так попадаем в массив. А массив смещений упорядочен по коду символов (цифр и др). А, понял. То есть смысла собственно в структуре нет, можно слепить все символы просто в массив? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 июня, 2020 Опубликовано 7 июня, 2020 · Жалоба 1 час назад, AHTOXA сказал: А, понял. То есть смысла собственно в структуре нет, можно слепить все символы просто в массив? Я не нашел иного способа для определения смещения начала каждого символа в массиве. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 7 июня, 2020 Опубликовано 7 июня, 2020 · Жалоба 1 час назад, ViKo сказал: Я не нашел иного способа для нахождения смещения начала каждого символа в массиве. int Fv(int ix) //ix - индекс символа { #define ZNAK_0 {1,2,3,4,5} #define ZNAK_1 {1,2,3,4,5,6} #define ZNAK_2 {1,2,3,4,5,6,7} #define m1(x) static u8 const concatAB(dummyZnak, x)[] = concatAB(ZNAK_, x) //#define concatAB_(a, b) a##b //#define concatAB(a, b) concatAB_(a, b) m1(0); m1(1); m1(2); struct Znakogenerator { u8 znak_0[sizeof(dummyZnak0)]; u8 znak_1[sizeof(dummyZnak1)]; u8 znak_2[sizeof(dummyZnak2)]; } static const znakogenerator = { .znak_0 = ZNAK_0, .znak_1 = ZNAK_1, .znak_2 = ZNAK_2 }; static u16 const offs[] = { offsetof(Znakogenerator, znak_0), offsetof(Znakogenerator, znak_1), offsetof(Znakogenerator, znak_2) }; //#define offsetof(typ, member) (size_t)&(((typ *)NULL)->member) return offs[ix]; //смещение начала символа ix } Это? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 8 июня, 2020 Опубликовано 8 июня, 2020 · Жалоба On 6/7/2020 at 11:11 AM, ViKo said: Я не нашел иного способа для определения смещения начала каждого символа в массиве. Я же выше вам приводил пример описания структуры символа и шрифта целиком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 8 июня, 2020 Опубликовано 8 июня, 2020 · Жалоба On 6/7/2020 at 8:58 AM, ViKo said: x893, я использую в данном проекте C99, поскольку передаю другому лицу. const меня от создания самих массивов, структуры не спасёт. А если typedef задать и для массивов пикселей символов, и для структуры? const тут для размещения во flash а не ram. Можете выкинуть const - суть от этого не изменится. Передавать можно любому лицу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 29 января Опубликовано 29 января · Жалоба В 05.06.2020 в 09:40, Сергей Борщ сказал: Неправда. Пустые скобки будут равносильны массиву неизвестного размера (incomplete array), который может располагаться только в конце структуры (flexible array member). Его размер определяется в момент определения структуры. Почему именно только в конце - становится понтяно, если поставить себя на место компилятора, который при компиляции другого файла увидит только объявление структуры из заголовочного файла, но не определение. Подниму тему)) Наткнулся щас на необходимость соорудить структуру с гибким размером элементов внутри нее. Это в Си, не плюсы. typedef struct { GPIO_TypeDef *gpio; u16 pinNum, pinMsk, mode; } sGPIOItem; typedef struct { u32 size; sGPIOItem item[]; } sGPIOList; static sGPIOList const GPIOMainBoard = { sizeof(GPIOMainBoard.item)/sizeof(GPIOMainBoard.item[0]), { {GPIOB, 10, B10, OUT_PP_10MHZ}, {GPIOA, 5, B5, IN_NOPULL}, {GPIOA, 4, B4, IN_NOPULL}, {GPIOB, 1, B1, OUT_PP_10MHZ} ... } }; Идея была в том, что создается универсальная прошивка под пару-тройку плат с разной разводкой пинов. Я хотел занести в структуру количество инициализируемых пинов. Естественно, компилятор ругается на строчку sizeof(GPIOMainBoard.item)/sizeof(GPIOMainBoard.item[0]), мол, invalid application of ‘sizeof’ to incomplete type ‘const sGPIOItem[]’. Соответственно, атрибуты типа sGPIOList (его размер, в частности) остаются неизменными вне зависимости от дальнейшего объявления конкретного экземпляра. Его размер будет равен размеру u32 size. Значит и sizeof(GPIOMainBoard) будет просто равен этому же u32. Жаль, конечно, что есть такое логическое западло. Хотелось автоматически заполнять размеры структуры, как никак. Щас просто пишется число, глазами считаются строчки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 января Опубликовано 29 января · Жалоба 6 minutes ago, Arlleex said: Щас просто пишется число, глазами считаются строчки. Сделайте NULL-terminated список. Конечно, есть шанс этот NULL забыть, зато считать не придется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 69 29 января Опубликовано 29 января · Жалоба 27 minutes ago, Arlleex said: Это в Си, не плюсы. добро пожаловать в волшебный мир препроцессора C... #define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), (sGPIOItem[]){__VA_ARGS__}} sGPIOList gpio = STRUCT_INIT( {GPIOB, 10, B10, OUT_PP_10MHZ}, {GPIOA, 5, B5, IN_NOPULL}, {GPIOA, 4, B4, IN_NOPULL}, {GPIOB, 1, B1, OUT_PP_10MHZ} ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 29 января Опубликовано 29 января · Жалоба 31 минуту назад, aaarrr сказал: Сделайте NULL-terminated список. Конечно, есть шанс этот NULL забыть, зато считать не придется. Если я правильно Вас понял, Вы имели в виду добавить в структуру Item-а еще одно поле, некий флажок. У обычных полей пусть он будет 0, а у самого крайнего 1, а дальше в цикле не пропустить этот самый 1? Или вон у меня указатель на GPIO есть, туда NULL вписать, а-ля список закончен. 5 минут назад, _pv сказал: добро пожаловать в волшебный мир препроцессора C... Как вариант, конечно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 января Опубликовано 29 января · Жалоба 4 minutes ago, Arlleex said: Или вон у меня указатель на GPIO есть, туда NULL вписать, а-ля список закончен. Именно так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 29 января Опубликовано 29 января · Жалоба 1 час назад, _pv сказал: добро пожаловать в волшебный мир препроцессора C... #define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), (sGPIOItem[]){__VA_ARGS__}} sGPIOList gpio = STRUCT_INIT( {GPIOB, 10, B10, OUT_PP_10MHZ}, {GPIOA, 5, B5, IN_NOPULL}, {GPIOA, 4, B4, IN_NOPULL}, {GPIOB, 1, B1, OUT_PP_10MHZ} ); И какой компилятор позволяет такое? IAR ожидаемо выдаёт ошибку: "cast to incomplete array type "sGPIOItem []" is not allowed". Имхо - без создания экземпляра массива так работать не будет. Я много раз пользовался подобным способом, но с созданием фейкового экземпляра массива. Вот как реализую аналогичную задачу в одном из проектов: Спойлер //USB Configuration Descriptor //All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) #define USB_CONFIG_DESCRIPTOR(typ, obj, dtyp) \ struct typ { \ UsbCfgDesc cfg; \ UsbIfaceDesc if0; \ UsbIfaceDesc if1; \ UsbEpDesc if1ep0; \ UsbIfaceDesc if2; \ UsbEpDesc if2ep0; \ u8 terminator; \ } const obj __align4 = { \ .cfg.bLength = sizeof(UsbCfgDesc), \ .cfg.bDescriptorType = dtyp, \ .cfg.wTotalLength = sizeof(typ) - sizeof(typ::terminator), \ .cfg.bNumInterfaces = 1, \ .cfg.bConfigurationValue = 1, \ .cfg.iConfiguration = 0, \ .cfg.bmAttr = USB_CONFIG_BUS_POWERED, \ .cfg.bMaxPower = USB_CONFIG_POWER_MA(100), \ \ .if0.bLength = sizeof(UsbIfaceDesc), \ .if0.bDescriptorType = USB_DESC_TYP_INTERFACE, \ .if0.bInterfaceNumber = 0, \ .if0.bAlternateSetting = 0, \ .if0.bNumEndpoints = 0, \ .if0.bInterfaceClass = USB_DEVICE_CLASS_VENDOR_SPECIFIC, \ .if0.bInterfaceSubClass = 255, \ .if0.bInterfaceProtocol = 255, \ .if0.iInterface = iInterface0, \ \ .if1.bLength = sizeof(UsbIfaceDesc), \ .if1.bDescriptorType = USB_DESC_TYP_INTERFACE, \ .if1.bInterfaceNumber = 0, \ .if1.bAlternateSetting = 1, \ .if1.bNumEndpoints = 1, \ .if1.bInterfaceClass = USB_DEVICE_CLASS_VENDOR_SPECIFIC, \ .if1.bInterfaceSubClass = 255, \ .if1.bInterfaceProtocol = 255, \ .if1.iInterface = iInterface1, \ \ .if1ep0.bLength = sizeof(UsbEpDesc), \ .if1ep0.bDescriptorType = USB_DESC_TYP_ENDPOINT, \ .if1ep0.bEndpointAddress = USB_EP_PHY2LOG(EPstream), \ .if1ep0.bmAttr.traTyp = USB_EP_TYP_ISOCHRONOUS, \ .if1ep0.bmAttr.syncTyp = USB_EP_SYNC_NO_SYNCHRONIZATION, \ .if1ep0.bmAttr.usageTyp = USB_EP_USAGE_DATA, \ .if1ep0.wMaxPacketSize = epSize_ASET1, \ .if1ep0.bInterval = 1, \ \ .if2.bLength = sizeof(UsbIfaceDesc), \ .if2.bDescriptorType = USB_DESC_TYP_INTERFACE, \ .if2.bInterfaceNumber = 0, \ .if2.bAlternateSetting = 2, \ .if2.bNumEndpoints = 1, \ .if2.bInterfaceClass = USB_DEVICE_CLASS_VENDOR_SPECIFIC, \ .if2.bInterfaceSubClass = 255, \ .if2.bInterfaceProtocol = 255, \ .if2.iInterface = iInterface2, \ \ .if2ep0.bLength = sizeof(UsbEpDesc), \ .if2ep0.bDescriptorType = USB_DESC_TYP_ENDPOINT, \ .if2ep0.bEndpointAddress = USB_EP_PHY2LOG(EPstream), \ .if2ep0.bmAttr.traTyp = USB_EP_TYP_ISOCHRONOUS, \ .if2ep0.bmAttr.syncTyp = USB_EP_SYNC_NO_SYNCHRONIZATION, \ .if2ep0.bmAttr.usageTyp = USB_EP_USAGE_DATA, \ .if2ep0.wMaxPacketSize = epSize_ASET2, \ .if2ep0.bInterval = 1, \ \ .terminator = 0 \ } USB_CONFIG_DESCRIPTOR(UsbFSConfigDescriptor, usbFSConfigDescriptor, USB_DESC_TYP_CONFIGURATION); USB_CONFIG_DESCRIPTOR(UsbHSConfigDescriptor, usbHSConfigDescriptor, USB_DESC_TYP_CONFIGURATION); USB_CONFIG_DESCRIPTOR(UsbFSOtherSpeed, usbFSOtherSpeed, USB_DESC_TYP_OTHER_SPEED_CONFIG); USB_CONFIG_DESCRIPTOR(UsbHSOtherSpeed, usbHSOtherSpeed, USB_DESC_TYP_OTHER_SPEED_CONFIG); См. как инициализируется .cfg.wTotalLength. Т.е. - один из членов структуры получает значение, вычисленное на основании размера экземпляра структуры. Вроде этого и хотел ТС. Компилится нормально в IAR for ARM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 69 29 января Опубликовано 29 января · Жалоба 46 minutes ago, jcxz said: И какой компилятор позволяет такое? IAR ожидаемо выдаёт ошибку: "cast to incomplete array type "sGPIOItem []" is not allowed". С компилятор любой должен, это вроде как стандартный способ инициализации массивов/структур через (type){x, y, z} но плюсовый может и не уметь, там что-то про сишные инициализации вроде бы только в с++23 наконец добавили. попробуйте переключить его в -std=c99 https://godbolt.org/z/TYnqzvqKj 1 hour ago, jcxz said: Вроде этого и хотел ТС. у ТСа там массив, неопределённой на момент определения (каламбур-с) длины [] есть, размер которого он хочет получить внутри этой же инициализации, которую компилятор ему не может дать, так как С теоретически позволяет ТСу после определения длины коварно продолжить инициализовать массив через именованную инициализацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 29 января Опубликовано 29 января · Жалоба 49 минут назад, _pv сказал: С компилятор любой должен, это вроде как стандартный способ инициализации массивов/структур через (type){x, y, z} но плюсовый может и не уметь, там что-то про сишные инициализации вроде бы только в с++23 наконец добавили. попробуйте переключить его в -std=c99 Переключил: Код находится в .c-файле: typedef struct { unsigned gpio; short pinNum; } sGPIOItem; typedef struct { unsigned size; sGPIOItem item[]; } sGPIOList; #define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), (sGPIOItem[]){__VA_ARGS__}} #if 1 sGPIOList const gpio = STRUCT_INIT( {0x101, 1}, {0x102, 2}, {0x103, 3} ); #endif Теперь выдаёт другую ошибку: Error[Pe144]: a value of type "sGPIOItem *" cannot be used to initialize an entity of type "unsigned int" PS: Вот так компилится без ошибок: #define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), {__VA_ARGS__}} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 69 29 января Опубликовано 29 января · Жалоба 57 minutes ago, jcxz said: Теперь выдаёт другую ошибку: Error[Pe144]: a value of type "sGPIOItem *" cannot be used to initialize an entity of type "unsigned int" каким образом у него там вообще int в этом месте образовался (парсер пролюбил "массивность" или вложенность стуктуры и сразу полез уровнем ниже unsigned gpio инициализировать?), и то что * и [] не абсолютно прям одно и то же, выглядит как-то не очень красиво. имхо что-то они там перемудрили с приведениями типов. 53 minutes ago, jcxz said: PS: Вот так компилится без ошибок: #define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), {__VA_ARGS__}} возможно какие-то тараканы самого iar, первое приведение внутри sizeof ему совсем не мешает, а при инициализации/присваивании, когда указан прям тот же тип поля что на самом деле есть и делать с ним он ничего не должен вообще - почему-то не нравится. но да, второе приведение {__VA_ARGS__} при инициализации поля структуры тут совсем не обязательно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться