Просветите, господа программисты.
- Войдите на сайт для отправки комментариев
Перетаскивал программный код в скетче с места на место. Не заметил как смахнул имя функции в вызове. Выражение осталось, но без имени функции. Должно было выглядеть так:
uint32_t a_mapped = map(x, 1, 100, 200, 300);
но стало выглядеть так
uint32_t a_mapped = (x, 1, 100, 200, 300);
Компилятор это молча съел и загрузил скетч в плату. Понятно, что скетч стал работать не так, как я рассчитывал. Не почуяв подвоха, я стал искать, где мог накосячить с алгоритмом. Казалось бы логика оставалась прежней, но ничего не работало. Какое-то время чесал репу, но наконец увидел эту странную конструкцию. Проверил еще раз. Компиляция проходит без ошибок, скетч грузится. Пошел дальше. Подставил перечисление через запятую в скобках, как параметр при вызове функции.
delay((x, 1, 100, 200, 300));
Компилятор съел и это без всякиж жалоб. Тут я понял, что пора лезть в гугл и искать, что бы это могло значить в соответствии с синтаксисом Си. Копался-копался, но так ничего вразумительного и не нашел.
Дизассемблировал загружаемый код. По нему видно, что в функцию передается последний член перечисления, т.е. 300. Усложнил конструкцию:
int x = 1000; uint32_t a_mapped = (x, 1, 100, 200, 300); delay((a_mapped, 1, 100, 200, 1000));
Из дизасемблера вижу, что первые две строки компилятор просто выбросил. Действия с ними связанные отсутствуют в загружаемом коде. Тут мне окончательно стало ясно, что я ничего не понимаю и я пришел сюда в поисках ответа.
Вопрос же простой: что означает перечисление через запятую в скобках с точки зрения синтаксиса языка Си, если речь не идет о случае передачи параметров при вызове функции?
Ищите среди операций хитрую операцию "запятая". :) В общем-то все верно. Её результат равен последнему выражению. Применяется там, где надо сделать несколько действий, а по контексту требуется одно выражение. Применение не рекомендуется как и для goto.
Ну да, так вроде и выходит. Если переписать последний пример так:
то никаких строк компилятор не выкидывает и значение 1000 передается в delay().
Операция "запятая" существует только в плюсах. Плюсы пользую редко, т.ч. о существовании такой фичи попросту не знал. Благодарю за просвещение.
что означает перечисление через запятую в скобках
Тоже, что и без скобок. Операция "запятая". Типичный пример использования:
Заметьте конструкцию "i++, j += 2" В этом месте допустимо только одно выражение. Нельзя использовать ни ";", ни {} - а операция "запятая" выручает.
В первых компилятора она ещё имела смысл в том. что позволяла лучше оптимизировать код, т.к. в ней содержится явное указание на то, что все операции, кроме последней исполняются только ради побочного эффекта (их результат никому не нужен), но сейчас это почти потеряло актуальность, т.к. теория компиляции шагнула вперёл и такие вещи и автоматы научились хорошо отслеживать.
Операция "запятая" существует только в плюсах.
Да, Господь с Вами. С самых первых версий С она была и сейчас есть.