vvppvv 0 19 февраля Опубликовано 19 февраля (изменено) · Жалоба Помогите, пожалуйста. Что-то я заблукатил в трёх соснах :)) Идея такая. Есть набор простых функций , без аргументов, которые должны вызываться последовательно, "по кольцу". Я решил организовать массив указателей на эти функции, с тем, чтобы просто инкрементировать указатель на этот массив, и как только он упрется в ноль - значит, достигнут конец списка, переход на начало. Ну, как со строками. Все хорошо, но я что-то никак не могу сказать компилятору, что мне нужен указатель равный нулю, в конце списка. Компилятор IAR AVR, язык Си: void UART_00 (void); // Функция передачи "MARK" void UART_01 (void); // Функция передачи "SPASE" void UART_02 (void); // Функция передачи 1-го байта битового поля void UART_03 (void); // Функция передачи 2-го байта битового поля void UART_04 (void); // Функция передачи 3-го байта битового поля void UART_05 (void); // Функция передачи 4-го байта битового поля void (* UART_NN[7])() = // Указатели на функции, последний равен нулю { & UART_00, & UART_01, & UART_02, & UART_03, & UART_04, & UART_05, & ((void(*)(void)) 0) // тут ругань, "Error[Pe158]: expression must be an lvalue or a function designator }; При этом софтварный ресет в виде: ((void(*)(void)) 0)(); как косвенный вызов, прекрасно компилится, т.е. в регистровую пару Z грузятся нули. Где я подтупливаю? :)) Изменено 19 февраля пользователем vvppvv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 19 февраля Опубликовано 19 февраля · Жалоба 2 минуты назад, vvppvv сказал: При этом софтварный ресет в виде: ((void(*)(void)) 0)(); Уберите амперсанд (операцию взятия адреса) при инициализации массива. Т.е. сделайте так: void (* UART_NN[7])() = // Указатели на функции, последний равен нулю { & UART_00, & UART_01, & UART_02, & UART_03, & UART_04, & UART_05, ((void(*)(void)) 0) // тут ругань, "Error[Pe158]: expression must be an lvalue or a function designator }; Да, элементов у вас в массиве семь, а не шесть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 19 февраля Опубликовано 19 февраля · Жалоба 5 minutes ago, vvppvv said: & ((void(*)(void)) 0) амперсанд (&) уберите и подумайте почему он ТУТ не нужен )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvppvv 0 19 февраля Опубликовано 19 февраля · Жалоба Ой спасибо! Вот ведь, блин... Посыпаю голову пеплом. ))) Семёрку убрал, она там не нужна. ВОт так вроде всё сжевалось: void (* UART_NN[])() = // Указатели на функции, последний равен нулю { UART_00, UART_01, UART_02, UART_03, UART_04, UART_05, ((void(*)(void)) 0) }; Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 19 февраля Опубликовано 19 февраля · Жалоба 7 minutes ago, vvppvv said: void (* UART_NN[7])() = оставьте пустые скобки [] , компилятор сам сделает массив нужного размера Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvppvv 0 19 февраля Опубликовано 19 февраля · Жалоба 2 minutes ago, Forger said: амперсанд (&) уберите и подумайте почему он ТУТ не нужен )) Изначально аперсандов и не было. Для указателя на первый элемент или функцию он же не нужен. Это я уже после начал втыкать всё, что попало, Добавлять скобки, убавлять, квадратно-гнездовых способом. Но компилятор фыркал, мотал головой и не поддавался, гад. :)))) Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 19 февраля Опубликовано 19 февраля · Жалоба Последний ноль не особо нужен, размер массива известен в момент компиляции, и ходить по нему можно с помощью sizeof(UART_NN) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 19 февраля Опубликовано 19 февраля · Жалоба 29 minutes ago, vvppvv said: void UART_00 (void); раз пошла "вкусовщина": void внутри тоже можно не писать, уже устаревший атавизм ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 февраля Опубликовано 19 февраля · Жалоба 8 minutes ago, Forger said: раз пошла "вкусовщина": void внутри тоже можно не писать, уже устаревший атавизм ) В сях int my_func() означает "функция, которая принимает любые аргументы". Атавизм, но никуда не денешься... В плюсах, действительно, можно (и нужно) не писать. 31 minutes ago, vvppvv said: ((void(*)(void)) 0) Уберите всю эту порнографию, пожалуйста. Есть же каноничный NULL (или nullptr). 40 minutes ago, vvppvv said: // Функция передачи "SPASE" SPACE, если уж "о вкусах" разговор зашёл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 19 февраля Опубликовано 19 февраля · Жалоба 4 минуты назад, esaulenka сказал: Уберите всю эту порнографию, пожалуйста. Есть же каноничный ... "Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам" (написано у вас в подписи) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 19 февраля Опубликовано 19 февраля · Жалоба 23 minutes ago, esaulenka said: nullptr он есть тока в плюсах )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 февраля Опубликовано 19 февраля · Жалоба 20 minutes ago, Forger said: он есть тока в плюсах )) https://en.cppreference.com/w/c/language/nullptr Но да, поддержку этой "новинки" можно ожидать в IAR AVR лет через н-цать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 62 19 февраля Опубликовано 19 февраля · Жалоба On 2/19/2024 at 10:51 AM, esaulenka said: В сях int my_func() означает "функция, которая принимает любые аргументы". А как использовать эти аргументы внутри функции ? Как к ним обращаться, если имена этих аргументов не определены ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvppvv 0 19 февраля Опубликовано 19 февраля (изменено) · Жалоба 1 hour ago, gerber said: Последний ноль не особо нужен, размер массива известен в момент компиляции, и ходить по нему можно с помощью sizeof(UART_NN) Да. Но проверка на ноль (проверка на достижение границы списка указателей) очень быстрая и простая, мне показалось так удобнее будет (указатель лежит в R13:R12): 480 if (!Func_UART_ptr) \ 000001FA 2D0C MOV R16, R12 \ 000001FC 290D OR R16, R13 \ 000001FE F419 BRNE ??main_14 ====== Я вот так сделал (без претензий на совершенство :)) ============== (** Func_UART_ptr++)(); // вызвать функцию из списка if (!Func_UART_ptr) // если была последняя, Func_UART_ptr = UART_NN; // то указатель на начало списка ("MARK") 1 hour ago, esaulenka said: Уберите всю эту порнографию, пожалуйста. Есть же каноничный NULL (или nullptr). И это пробовал. Нет его в IAR EW AVR 7.30.5. компилятор ругается. 1 hour ago, esaulenka said: SPACE, если уж "о вкусах" разговор зашёл. Да, разумеется. Описька.)) Изменено 19 февраля пользователем vvppvv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 19 февраля Опубликовано 19 февраля · Жалоба 39 minutes ago, esaulenka said: Но да, поддержку этой "новинки" можно ожидать в IAR AVR лет через н-цать. дык, в кейле давно это использую вместо NULL, прекрасно работает ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться