Перейти к содержанию
    

(Не)доработки языков программирования

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".

Очень спорная потребность: могут начаться проблемы как минимум со сторонним кодом, где дублированные значения могут быть созданы намеренно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Я писал, что хотелось бы ошибку при не равно, а не только при больше. Что будет при меньше я прекрасно знаю, именно поэтому и написал такой пункт.

 

В голом виде (без 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 имеют одинаковые значения и при этом это нормально скомпилится. А не должно компилиться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И что? Как это поможет от дубликатов? Вот у Вас AF_TIM1 и AF_TIM2 имеют одинаковые значения и при этом это нормально скомпилится. А не должно компилиться.

Не согласен с вашим предложением, вот что. :rolleyes: Потому что хочу иметь одинаковые значения в перечислении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не согласен с вашим предложением, вот что. :rolleyes: Потому что хочу иметь одинаковые значения в перечислении.

Блин! Ещё раз: я не предлагал изменить логику работы enum конечно же! А добавить новый механизм, в котором одинаковые значения запрещены.

Я тоже использую enum-ы с одинаковыми значениями. Когда это надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Теперь расскажите это создателям Паскаля и тем десяткам тысяч программистов кто его использует. :laughing:

Тогда тоже пишите в паскале. В чем проблема? :smile3046:

 

К слову, в C# со строками все это сделано гораздо удобнее, чем в голом C/C++, но опять-таки в основном за счет очень толстых библиотек.

 

А речь как я понял про С/C++. Коли так, то почти все ваши пожелания - пока что фантастика.

Посмотрите историю эволюции C++ (03 - 11 - 14 - 17) - там появляются новые фишки, но совсем другого рода. К вашим паскале-подобным "удобствам" отношения не имеют.

И наверняка на то есть причины - новые стандарты появляются в голове не одного человека, в этом участвует сообщество серьезных мега-программеров.

 

Поэтому я согласен лишь с одним пунктом (1): за более жесткий контроль числа инициализаторов массива. Имхо, весьма полезная "фишка".

Пусть и не ошибка "вылетает", но хотя бы варнинг.

 

А добавить новый механизм, в котором одинаковые значения запрещены.

Это легко реализовать в run-time, всего один раз запускать проверку на дубликаты значений.

Я бы сделал так: const struct, или лучше: constexpr struct, дав значения каждом полю прямо при объявлении (С++11).

 

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

По мне - экзотика :laughing: .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Блин! Ещё раз: я не предлагал изменить логику работы enum конечно же! А добавить новый механизм, в котором одинаковые значения запрещены.

Я тоже использую enum-ы с одинаковыми значениями. Когда это надо.

Что-то типа unique_case в SV? Атрибут такой ввести? Ну, пусть. :santa2:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поэтому я согласен лишь с одним пунктом (1): за более жесткий контроль числа инициализаторов массива. Имхо, весьма полезная "фишка".

Пусть и не ошибка "вылетает", но хотя бы варнинг.

const int array_size = 3;
int array[] = {1,2};
static_assert(sizeof(array)/sizeof(array[0]) == array_size, "ERROR!!!");

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Было-бы лучше, если бы в си, при объявлении инициализированного массива с явно указанной размерностью

int m[N] = {1, 2, 3};

компилятор выдавал бы ошибку компиляции если количество инициализаторов не равно N.

. . . .

#ifdef DEBUG
if( m[N-1] == 0x00 ) . . . .
#endif

Ошибка вылезет на этапе исполнения. Но тут вопрос шашечек или ехать. Да и не всегда это ошибка.

А включать-выключать warning - лишние хлопоты. (например 20 процентов массивов надо контролировать на заполнение, а остальные - нет).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 для анализа подобных массивов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

template < int...Params > struct AAA {
  static_assert(sizeof...(Params) == 4, "ERROR!!!");
  int aaa[4] = {Params...};
};
AAA<1,2,3,4> aaa;

Обертку для удобства сделайте сами.

 

А вообще при желании всяческих проверок и т.п. добро пожаловать в метапрограммирование и stl

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

добро пожаловать в метапрограммирование

В данном случае это уже некий сарказм :)

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В данном случае это уже некий сарказм :)

А чего такого) Мы уже используем прелести Си++11 для микроконтроллеров. Можно и Си++14. Удобно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мы уже используем прелести Си++11 для микроконтроллеров. Можно и Си++14. Удобно.

Аналогично! ;)

Сокращается объем текста кода, его проще читать, да и размер прошивки тоже выходит меньше.

Имхо, С++14 пока что рановат в обычных МК-проектах, да и мало кто из компиляторов под МК его полностью держит, но ... (С) "еще не вечер" ;)

 

Но городить метапрограммированием банальную проверку массива на недостающие инициализаторы - это, имхо, уже перебор. Это уже прям "масло масляное", имхо ))

Наверно, проще будет вообще отказаться от таких "странных" инициализируемых не нулем массивов и переделать их под constexpr структуры с явной инициализацией полей.

Например: коды команд, строковые коды запросов/ответов для, например, внешнего модема.

 

Я знаю лишь одно применение массивов, инициализируемых при объявлении: внешний ресурс в виде jpg-картинки, растровых шрифтов и т. п.

Но обычно они все инициализируются не вручную, а с помощью соотв. внешнего софта.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имхо, С++14 пока что рановат в обычных МК-проектах, да и мало кто из компиляторов под МК его полностью держит, но ... (С) "еще не вечер" ;)
IAR ARM начиная с версии 8 поддерживает как 11 так и 14. Да и разница между 11 и 14 заметна не любому глазу.

 

Но городить проверку массива на недостающие инициализаторы метапрограммированием - это, имхо, уже перебор. Это уже масло масляное, имхо ))

Наверно, проще будет вообще отказаться от таких "странных" инициализируемых не нулем массивов и переделать их под constexpr структуры с явной инициализацией полей.

Посмотрите в сторону std::array. С ним можно делать все тоже самое.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...