Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 05:37:37

имхо: избавляться от варнингов нет необходимости, если они на самом деле являются следствием реализации алгоритма. варнинг говорит о том, что мнение компилятора и программиста по данному вопросу МОГУТ расходиться, но не факт, что это представляет проблему. приведение типа в данном случае является страусиной политикой: не вижу, значит, это не существует. а это заведомо хуже, чем вижу, но не боюсь, ибо...

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

для полностью "прозрачной" реализации я бы сделал как-то так:
Код:
typedef enum{
   DIR_FIRST,
// добавлять ниже, но не выше!
   DIR_NORD,
   DIR_EAST,
   DIR_SOUTH,
   DIR_WEST,
// ниже не добавлять!
   DIR_LAST
} direction_t;

direction_t rotate_right(direction_t current_dir){
   if(++current_dir >= DIR_LAST) current_dir = DIR_FIRST + 1;
   return current_dir;
}

direction_t rotate_left(direction_t current_dir){
   if(--current_dir == DIR_FIRST) current_dir = DIR_LAST - 1;
   return current_dir;

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 11:07:36

имхо: избавляться от варнингов нет необходимости, если они на самом деле являются следствием реализации алгоритма. варнинг говорит о том, что мнение компилятора и программиста по данному вопросу МОГУТ расходиться, но не факт, что это представляет проблему. приведение типа в данном случае является страусиной политикой: не вижу, значит, это не существует. а это заведомо хуже, чем вижу, но не боюсь, ибо...

В корне неправильно!
От варнингов нужно избавляться всегда. Если Ваше мнение расходится с мнением компилятора хуже будет только вам. Потому что компилятор сделает по-своему. Он вас предупредил, Вы проигнорили - дальше виноваты сами за последствия.
Если на вас едет паровоз, машинист видит вас и предупреждает гудком чтобы Вы ушли с рельс. Если вы это проигнорите - паровозу от этого не поплохеет. Ну разве что скотоотбойник запачкает :)))

А как именно избавляться - это уже можно делать по-разному.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 12:03:46

jcxz, тут я с Вами не согласен. Простейший пример. Имеем таблицу указателей на функции. Пусть у функции один параметр. Причем части функций этот параметр просто не нужен, хотя остальные функции без него обойтись не могут. Получаем два варианта решения:
1. Игнорируем конкретное предупреждение о неиспольуемом значении параметра:
Код:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
...
#pragma GCC diagnostic pop

2. Усложняем алгоритм, разбивая таблицу на две и выполняя поиск нужного обработчика в обоих таблицах.

Пример:
Код:
typedef struct ir_cmd_st {
  uint8_t   code;
  uint8_t (*ir_handler)(uint8_t);
} ir_cmd_t;

static ir_cmd_t ir_cmd_table[] = {
  { IR_NEC_CMD_UP,    ir_handler_brightness },
  { IR_NEC_CMD_DOWN,  ir_handler_brightness },
  { IR_NEC_CMD_LEFT,  ir_handler_pgm_prev},
  { IR_NEC_CMD_RIGHT, ir_handler_pgm_next},
  { IR_NEC_CMD_OK,    ir_handler_switch_channel},
  { IR_NEC_CMD_0,     ir_handler_pgm_no},
  { IR_NEC_CMD_1,     ir_handler_pgm_no},
  { IR_NEC_CMD_2,     ir_handler_pgm_no},
  { IR_NEC_CMD_3,     ir_handler_pgm_no},
  { IR_NEC_CMD_4,     ir_handler_pgm_no},
  { IR_NEC_CMD_5,     ir_handler_pgm_no},
  { IR_NEC_CMD_6,     ir_handler_pgm_no},
  { IR_NEC_CMD_7,     ir_handler_pgm_no},
  { IR_NEC_CMD_8,     ir_handler_pgm_no},
  { IR_NEC_CMD_9,     ir_handler_pgm_no} };


Здесь обработчками ir_handler_pgm_prev(), ir_handler_pgm_next() и ir_handler_switch_channel() код нажатой кнопки на ИК пульте совершенно не нужен, тогда как обработчиками ir_handler_brightness() и ir_handler_pgm_no() он необходим.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 12:15:03

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

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 12:48:37

GARMIN, например, на SDCС и STM8S, для которого был использован данный код, Ваш подход приведет к дополнительным машинным командам в каждом обработчике, которому нужен код клавиши. Тогда как в моем случае, код клавиши сразу оказывается в аккумуляторе, где он и был в вызывающей программе при поиске обработчика в таблице. Мне даже в память этот код не нужно сохранять.

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

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 12:56:45

ПростоНуб, вызываешь с параметром функцию без параметров? И эти люди запрещают мне перегрузку :)

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 13:07:06

Убрал.
Нарушение Правил форума п. 2.3
aen

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 13:23:21

VladislavS, Вы как всегда не в теме )))
В массиве указателей на функцию все функции должны быть с одинаковым возвращаемым значением и с одинаковым набором параметров. Поэтому, если каким-то из этих функций нужен для алгоритма параметр, то его приходится передавать всем функциям в этом массиве.
То есть, тут и близко не пахнет перегрузкой. Это разные функции выполняющие разные действия при возникновении подобных событий. В данном случае - нажатии разных кнопок на одном и том же пульте ДУ на ИК лучах.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 13:59:50

Я не про перегрузку спрашивал, а про вызов функции которая не принимает параметр вызовом с параметром. Это вообще нормально?

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 14:08:37

VladislavS, что значит "не принимает"? Я не понимаю Вашей терминологии.
Я вел речь только о тех случаях, когда один или несколько параметров функции не используются ей именно в целях унификации вызова в машинных кодах, увеличивая производительность кода и уменьшая его размер. Тогда как перегрузка в подобных случаях приводит к обратному - к увеличению размера кода и понижению быстродействия, так как компилятор уже не может развернуть такой код в таблицу вызовов функций.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 14:15:15

То есть, все обработчики имеют одинаковый интетфейс? Тогда ладною. А то по тексту читалось что часть из них принимеют void, а часть принимают что-то.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 14:22:13

ПростоНуб, можно и разное количество аргументов делать, но для этого придется с va_args заморачиваться, что жрет ресурсы... Проще уж написать __attribute__((unused)) на неиспользуемые функциями аргументы.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 14:30:36

Eddy_Em, можно, но далеко не во всех компиляторах. Например, в SDCC только так:
Код:
#pragma save
#pragma disable_warning 85
...
#pragma restore

А данную конструкцию препроцессором намного проще сделать переносимой под разные компиляторы, чем __attribute__()

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 14:34:15

SDCC - вообще жутчайший компилятор! Оптимизацией там вообще не пахнет, иной раз как глянешь листинг - жесть! Приходится местами вручную оптимизировать (а то и ассемблерные вставки делать).
Но, к сожалению, порта gcc для STM8 нет, и приходится кривым sdcc собирать (больше-то компиляторов и нет под этот МК).

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 14:47:11

Eddy_Em, и не только для STM8. Для ряда МК он или единственный, или лучший вариант.
На самом деле, начиная с 3.8 оптимизацией там запахло. Даже 3.7 после 3.6 показалась манной небесной )
По крайней мере, уже начиная с 3.7 особого смысла использовать вместо SDCC COSMIC или IAR не стало.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 15:04:21

Подскажите пожалуйста: если локальную переменную объявить как static то ее значение сохраняется при выходе из функции. Но что будет если эту функцию вызывать рекурсивно? Будет выделятся память по мере вызовов и сохранятся? Интересует на языке Си.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 15:08:58

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

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 15:10:24

Значит можно не боятся переполнения стека этими переменными.

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 15:12:51

Прикольно. Чисто алгоритмически не важно это одна или много переменных, а за стек переживаем?

Re: Вопросы по С/С++ (СИ)

Чт окт 03, 2019 15:14:59

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