Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба 1. Было-бы лучше, если бы в си, при объявлении инициализированного массива с явно указанной размерностью int m[N] = {1, 2, 3};компилятор выдавал бы ошибку компиляции если количество инициализаторов не равно N. Дык, он и так ругается, но лишь в одном случае - число инициализаторов больше размерности массива. Увы, не ругается, если меньше. Просто "забивает" недостающие нулями. Это действительно неудобно. 2. Было бы очень полезно, если бы в константных выражениях можно было смешивать строки и значения: В голом виде (без STL и типа того), подобная затея - это рассадник опасных и довольно коварных ошибок на абсолютно ровном месте: как минимум нужно контролировать размерности типов данных на разных платформах, в т. ч. "банальный" char. Вангую головную боль, в принципе, на ровном месте. К тому же такое "оружие" опасно отдавать в руки новичками. 3. Было бы классно если бы строковые константы можно было задавать не только в форме ASCIIZ (завершающийся нулём набор символов), но и в виде: длина_строки "строка" (без 0 в конце). const char t1[] = "012"; const char t2[3] = { '0', '1', '2' }; t1 будет иметь длину 4 байта, а t2 - 3 байта. Определить длину t1 можно лишь найдя ноль в конце, у t2 размер указан явно. Все логично. Но, если убрать ноль у t1, сделав его длину 3 байта, то как в коде понять, что он имеет размер в 3 байта? Как отличить его с "классической" строкой в 4 байта? Путаница на абсолютно ровном месте. Имхо, опасная блажь! 4. Полезно было бы в stdlib в обязательном порядке внести прототип функции _Printf(void *(*)(void *), void *, char *, ...) - т.е. функцию из семейства printf...() передающую поток выводимых символов не на stdout (printf()) или в память (sprintf()), а в callback-функцию (первый аргумент _Printf()). Это легко делается и сейчас: достаточно лишь "перегрузить" встроенную функцию "putc" своей собственной реализацией, игнорируя второй параметр FILE *. Вот ее прототип: int putc(int ch, FILE *stream); В этом случае при сборке проекта линкер "возьмет" реализацию putc из вашего кода, а не штатную из библиотеки stdio. 5. Было бы очень полезно наличие в языке возможностей задания списков define-ов (или enum) с уникальными значениями. Т.е. чтобы на: enum {V_1 = 11, V_2 = 12, V_3 = 13, V_4 = 11, ...}; вылетало на ошибке компиляции типа: "V_4 - duplicate value". Очень спорная потребность: могут начаться проблемы как минимум со сторонним кодом, где дублированные значения могут быть созданы намеренно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба 5. Было бы очень полезно наличие в языке возможностей задания списков define-ов (или enum) с уникальными значениями. Т.е. чтобы на: enum {V_1 = 11, V_2 = 12, V_3 = 13, V_4 = 11, ...}; вылетало на ошибке компиляции типа: "V_4 - duplicate value". Не согласен. Личный пример, как описываю альтернативные функции для портов STM32: //! GPIO Alternate Functions typedef enum { AF_SYSTEM, //!< AF0 - SYSTEM* AF_TIM1, //!< AF1 - TIM1/2 AF_TIM2 = 1, //!< AF1 - TIM1/2 AF_TIM3, //!< AF2 - TIM3/4/5 AF_TIM4 = 2, //!< AF2 - TIM3/4/5 AF_TIM5 = 2, //!< AF2 - TIM3/4/5 AF_TIM8, //!< AF3 - TIM9/10/11 AF_TIM9 = 3, //!< AF3 - TIM9/10/11 AF_TIM10 = 3, //!< AF3 - TIM9/10/11 AF_TIM11 = 3, //!< AF3 - TIM9/10/11 AF_I2C1, //!< AF4 - I2C1/2/3 AF_I2C2 = 4, //!< AF4 - I2C1/2/3 AF_I2C3 = 4, //!< AF4 - I2C1/2/3 AF_SPI1, //!< AF5 - SPI1/2 AF_SPI2 = 5, //!< AF5 - SPI1/2 AF_SPI3, //!< AF6 - SPI3 AF_USART1, //!< AF7 - USART1/2/3 AF_USART2 = 7, //!< AF7 - USART1/2/3 AF_USART3 = 7, //!< AF7 - USART1/2/3 AF_USART4, //!< AF8 - USART4/5/6 AF_USART5 = 8, //!< AF8 - USART4/5/6 AF_USART6 = 8, //!< AF8 - USART4/5/6 AF_CAN1, //!< AF9 - CAN1/2 AF_CAN2 = 9, //!< AF9 - CAN1/2 AF_TIM12 = 9, //!< AF9 - TIM12/13/14 AF_TIM13 = 9, //!< AF9 - TIM12/13/14 AF_TIM14 = 9, //!< AF9 - TIM12/13/14 AF_OTGFS, //!< AF10 - OTGFS AF_OTGHS = 10, //!< AF10 - OTGHS AF_ETH, //!< AF11 - ETH AF_FSMC, //!< AF12 - FSMC AF_SDIO = 12, //!< AF12 - SDIO AF_OTGHS_ = 12, //!< AF12 - OTGHS AF_DCMI, //!< AF13 - DCMI AF_AF14, //!< AF14 - RI AF_EVENT //!< AF15 - SYSTEM (EVENTOUT) } GPIO_AFLH_t; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Дык, он и так ругается, но лишь в одном случае - число инициализаторов больше размерности массива. Я писал, что хотелось бы ошибку при не равно, а не только при больше. Что будет при меньше я прекрасно знаю, именно поэтому и написал такой пункт. В голом виде (без STL и типа того), подобная затея - это рассадник опасных и довольно коварных ошибок на абсолютно ровном месте: В чём именно опасность? Не понял. :wacko: Да, программировать нужно уметь и язык знать - это вроде не должно вызывать сомнений. И в ассемблерах такая возможность часто имеется. Но, если убрать ноль у t1, сделав его длину 3 байта, то как в коде понять, что он имеет размер в 3 байта? Как отличить его с "классической" строкой в 4 байта? Прочитайте моё сообщение внимательнее прежде чем критиковать. Я пишу, что хотелось бы не только "классические" строки (это называется обычно ASCIIZ), а и строки в формате длина,символы_без_0_в_конце. Путаница на абсолютно ровном месте. Имхо, опасная блажь! Теперь расскажите это создателям Паскаля и тем десяткам тысяч программистов кто его использует. :laughing: Если Вы не в состоянии понять для чего это нужно, это ещё не повод говорить "блажь". Например: программа получает текстовый поток данных, который разбивает на лексемы (слова) заменяя строковые значения лексем их номерами из некоего словаря. Значит - в программе есть некий массив лексем, константный и возможно довольно большой. Теперь объясните, пожалуйста, как эффективно (т.е. - быстро) организовать поиск лексем в таком массиве, если принять, что лексемы имеют сильно разные размеры и что для удобства читаемости (и редактирования) исходника лексемы очень желательно иметь в виде строк (а не в виде {'a','b',...}) и лексемы нельзя расположить в некоем удобном для поиска порядке, а порядок их расположения одна относительно другой определяется другими критериями (разбивка на логические группы, связь со значениями define-ов и т.п.) ??? Так вот: с байтом длины поиск в таком списке лексем будет идти гораздо быстрее чем со списком ASCIIZ-строк. Это легко делается и сейчас: достаточно лишь "перегрузить" встроенную функцию "putc" своей собственной реализацией, игнорируя второй параметр FILE *. Данный пункт скорее касается компиляторов для PC, потому что в тех компиляторах для МК, с коими я работал (IAR и в CCS) такая функция и так имеется (_Printf()). А в компиляторах на PC часто нежелательно перегружать putc(), потому что она может быть нужна. Очень спорная потребность: могут начаться проблемы как минимум со сторонним кодом, где дублированные значения могут быть созданы намеренно. Внимание: я не пишу что нужно изменить работу enum, я пишу что хотелось бы такой механизм. А назваться он естественно должен не enum. Enum там приведён для примера списка, который хотелось бы переделать по другому. Не согласен. Личный пример, как описываю альтернативные функции для портов STM32: И что? Как это поможет от дубликатов? Вот у Вас AF_TIM1 и AF_TIM2 имеют одинаковые значения и при этом это нормально скомпилится. А не должно компилиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба И что? Как это поможет от дубликатов? Вот у Вас AF_TIM1 и AF_TIM2 имеют одинаковые значения и при этом это нормально скомпилится. А не должно компилиться. Не согласен с вашим предложением, вот что. :rolleyes: Потому что хочу иметь одинаковые значения в перечислении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Не согласен с вашим предложением, вот что. :rolleyes: Потому что хочу иметь одинаковые значения в перечислении. Блин! Ещё раз: я не предлагал изменить логику работы enum конечно же! А добавить новый механизм, в котором одинаковые значения запрещены. Я тоже использую enum-ы с одинаковыми значениями. Когда это надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Теперь расскажите это создателям Паскаля и тем десяткам тысяч программистов кто его использует. :laughing: Тогда тоже пишите в паскале. В чем проблема? :smile3046: К слову, в C# со строками все это сделано гораздо удобнее, чем в голом C/C++, но опять-таки в основном за счет очень толстых библиотек. А речь как я понял про С/C++. Коли так, то почти все ваши пожелания - пока что фантастика. Посмотрите историю эволюции C++ (03 - 11 - 14 - 17) - там появляются новые фишки, но совсем другого рода. К вашим паскале-подобным "удобствам" отношения не имеют. И наверняка на то есть причины - новые стандарты появляются в голове не одного человека, в этом участвует сообщество серьезных мега-программеров. Поэтому я согласен лишь с одним пунктом (1): за более жесткий контроль числа инициализаторов массива. Имхо, весьма полезная "фишка". Пусть и не ошибка "вылетает", но хотя бы варнинг. А добавить новый механизм, в котором одинаковые значения запрещены. Это легко реализовать в run-time, всего один раз запускать проверку на дубликаты значений. Я бы сделал так: const struct, или лучше: constexpr struct, дав значения каждом полю прямо при объявлении (С++11). Кстати, мне еще никогда не приходилось сталкиваться с таким - механизм, в котором одинаковые значения запрещены, и в чужом коде тоже. По мне - экзотика :laughing: . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Блин! Ещё раз: я не предлагал изменить логику работы enum конечно же! А добавить новый механизм, в котором одинаковые значения запрещены. Я тоже использую enum-ы с одинаковыми значениями. Когда это надо. Что-то типа unique_case в SV? Атрибут такой ввести? Ну, пусть. :santa2: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Поэтому я согласен лишь с одним пунктом (1): за более жесткий контроль числа инициализаторов массива. Имхо, весьма полезная "фишка". Пусть и не ошибка "вылетает", но хотя бы варнинг. const int array_size = 3; int array[] = {1,2}; static_assert(sizeof(array)/sizeof(array[0]) == array_size, "ERROR!!!"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба 1. Было-бы лучше, если бы в си, при объявлении инициализированного массива с явно указанной размерностью int m[N] = {1, 2, 3}; компилятор выдавал бы ошибку компиляции если количество инициализаторов не равно N. . . . . #ifdef DEBUG if( m[N-1] == 0x00 ) . . . . #endif Ошибка вылезет на этапе исполнения. Но тут вопрос шашечек или ехать. Да и не всегда это ошибка. А включать-выключать warning - лишние хлопоты. (например 20 процентов массивов надо контролировать на заполнение, а остальные - нет). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба const int array_size = 3; int array[] = {1,2}; static_assert(sizeof(array)/sizeof(array[0]) == array_size, "ERROR!!!"); Отличное решение! Но, увы, оно не работает, если явно указать размер массива: int array[3] = {1,2}; Компилятор не ругается, а последнее значение array[2] он тупо заполнит нулем. А если речь, например, про float array[3] = { 1, 2 }, то в array[2] будет не ожидаемый float 0.0, а просто 4 нулевых байта... Скверная ситуация (( И то не факт, что именно так поступит тот или иной компилятор - нужно проверять. Отсюда вопрос: а надо ли? На край хотя бы встроенная локальная #pragma для анализа подобных массивов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба template < int...Params > struct AAA { static_assert(sizeof...(Params) == 4, "ERROR!!!"); int aaa[4] = {Params...}; }; AAA<1,2,3,4> aaa; Обертку для удобства сделайте сами. А вообще при желании всяческих проверок и т.п. добро пожаловать в метапрограммирование и stl Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба добро пожаловать в метапрограммирование В данном случае это уже некий сарказм :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба В данном случае это уже некий сарказм :) А чего такого) Мы уже используем прелести Си++11 для микроконтроллеров. Можно и Си++14. Удобно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Мы уже используем прелести Си++11 для микроконтроллеров. Можно и Си++14. Удобно. Аналогично! ;) Сокращается объем текста кода, его проще читать, да и размер прошивки тоже выходит меньше. Имхо, С++14 пока что рановат в обычных МК-проектах, да и мало кто из компиляторов под МК его полностью держит, но ... (С) "еще не вечер" ;) Но городить метапрограммированием банальную проверку массива на недостающие инициализаторы - это, имхо, уже перебор. Это уже прям "масло масляное", имхо )) Наверно, проще будет вообще отказаться от таких "странных" инициализируемых не нулем массивов и переделать их под constexpr структуры с явной инициализацией полей. Например: коды команд, строковые коды запросов/ответов для, например, внешнего модема. Я знаю лишь одно применение массивов, инициализируемых при объявлении: внешний ресурс в виде jpg-картинки, растровых шрифтов и т. п. Но обычно они все инициализируются не вручную, а с помощью соотв. внешнего софта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Имхо, С++14 пока что рановат в обычных МК-проектах, да и мало кто из компиляторов под МК его полностью держит, но ... (С) "еще не вечер" ;)IAR ARM начиная с версии 8 поддерживает как 11 так и 14. Да и разница между 11 и 14 заметна не любому глазу. Но городить проверку массива на недостающие инициализаторы метапрограммированием - это, имхо, уже перебор. Это уже масло масляное, имхо )) Наверно, проще будет вообще отказаться от таких "странных" инициализируемых не нулем массивов и переделать их под constexpr структуры с явной инициализацией полей. Посмотрите в сторону std::array. С ним можно делать все тоже самое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться