esaulenka 7 19 февраля Опубликовано 19 февраля · Жалоба 29 minutes ago, dimka76 said: А как использовать эти аргументы внутри функции ? Это у K&R надо спрашивать, зачем оно такое придумывалось 🙂 Но вот такое должно нормально собираться: // myfile.h int myfunc(); // myfile.c int myfunc(int x) { return x + 3; } // main.c #include "myfile.h" ... myfunc("hello!", 123); Зачем оно сейчас, кроме как побольнее в ногу стрельнуть, я не знаю. Но вывод из этого всего простой - "параметр" void в сишном коде лучше не убирать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 19 февраля Опубликовано 19 февраля · Жалоба 37 минут назад, dimka76 сказал: А как использовать эти аргументы внутри функции ? Как к ним обращаться, если имена этих аргументов не определены ? int func() int a, b, c { return a + b + c; } int func(int, int, int); main() { int sum = func(10, 20, 30); printf("%d", sum); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 февраля Опубликовано 19 февраля · Жалоба 27 minutes ago, vvppvv said: И это пробовал. Нет его в IAR EW AVR 7.30.5. компилятор ругается. Это часть стандартной библиотеки: https://en.cppreference.com/w/c/types/NULL Сделайте include <stdlib.h> или include <stddef.h> Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 19 февраля Опубликовано 19 февраля · Жалоба 19 минут назад, vvppvv сказал: Да. Но проверка на ноль (проверка на достижение границы списка указателей) очень быстрая и простая, ====== Я вот так сделал (без претензий на совершенство :)) ============== (** Func_UART_ptr++)(); // вызвать функцию из списка if (!Func_UART_ptr) // если была последняя, Func_UART_ptr = UART_NN; // то указатель на начало списка ("MARK") Есть такой термин "безопасное программирование". К примеру, что будет с вашим кодом, если список функций пуст (начинается с NULL)? Или в процессе отладки вы захотите (временно) отключить вызов какой-либо функции, заменив её на NULL в массиве? И чем будет ограничен вызов функций, если забыть завершить массив нулём? В последнем случае код может оказаться случайно рабочим, вы забудете про него на пару лет, а при очередной модификации начнутся глюки, и вы будете долго ломать голову. Логично и безопасно перебрать все элементы массива и вызвать ненулевые, разве нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 19 февраля Опубликовано 19 февраля · Жалоба 4 minutes ago, gerber said: Логично и безопасно перебрать все элементы массива и вызвать ненулевые, разве нет? нулевые можно заполнить функциями-заглушками, которые в порт отладки скажут о факте их вызова, тогда просто вызываются все, что есть в массиве т.е. массив еще на этапе создания/объявления сразу заполняется указателями на одну и ту же "пустую" функцию, ведь по-умолчанию там будут просто нули с другой стороны существуют итераторы ... (это такой сознательный вбросик в тему ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 224 19 февраля Опубликовано 19 февраля · Жалоба 2 часа назад, vvppvv сказал: Все хорошо, но я что-то никак не могу сказать компилятору, что мне нужен указатель равный нулю, в конце списка. Может в конце списка лучше хранить не NULL, а указатель на функцию, которая и переставит указатель списка на начало? Тогда и дополнительных проверок на NULL не потребуется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 19 февраля Опубликовано 19 февраля · Жалоба On 2/19/2024 at 12:46 PM, Arlleex said: int func() int a, b, c { return a + b + c; } Не, это получается в стиле K&R. А речь ведь про такое int foo() { return 0; } int main() { foo(5); return 0; } Компилируется без ошибок и предупреждений. И вот как здесь этот аргумент использовать ? Выходит, что никак. On 2/19/2024 at 12:44 PM, esaulenka said: Зачем оно сейчас, кроме как побольнее в ногу стрельнуть, я не знаю. Чтобы запутать тех, кто после вас будет этим кодом пользоваться Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 19 февраля Опубликовано 19 февраля · Жалоба 19 минут назад, dimka76 сказал: int foo() { return 0; } int main() { foo(5); return 0; } Компилируется без ошибок и предупреждений. "Этот ваш..." GCC - инородный компилятор, потому что нормальный компилятор выдаст сообщение о несоответствии вызова: User\main.c(80): warning: #140-D: too many arguments in function call А все потому, что если Вы используете форму декларатора определения функции с пустыми скобками, то компилятору это строгое указание, что функция не принимает аргументов (по сути, аналог int foo(void) { return 0; }). Не скажу, является ли это UB - это надо лезть в стандарт. Предположу, что должен быть UB. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 19 февраля Опубликовано 19 февраля · Жалоба On 2/19/2024 at 1:42 PM, Arlleex said: "Этот ваш..." GCC - инородный компилятор, потому что нормальный компилятор выдаст сообщение о несоответствии вызова: User\main.c(80): warning: #140-D: too many arguments in function call А все потому, что если Вы используете форму декларатора определения функции с пустыми скобками, то компилятору это строгое указание, что функция не принимает аргументов (по сути, аналог int foo(void) { return 0; }). Не скажу, является ли это UB - это надо лезть в стандарт. Предположу, что должен быть UB. Нормально там все у GCC ))))) Вот если функцию объявить как int foo(void) { return 0; } И при вызове попытаться в нее что-то передать, то вот тогда компилятор и выдаст ошибку. On 2/19/2024 at 1:42 PM, Arlleex said: по сути, аналог int foo(void) { return 0; } Это не аналог. Вот пример из самого стандарта и комментарии к примеру Quote EXAMPLE 1 The declaration int f(void), *fip(), (*pfi)(); declares a function f with no parameters returning an int, a function fip with no parameter specification Видите ? Функция без параметров и функция без описания параметров. Функция без описания параметров это по сути функция с переменным числом аргументов. Что-то наподобие printf. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 19 февраля Опубликовано 19 февраля · Жалоба 6 minutes ago, dimka76 said: И при вызове попытаться в нее что-то передать, то вот тогда компилятор и выдаст ошибку. а вообще по практике кто-нить когда нить пытался передавать параметры в такие функции (), заранее зная, что они их проигнорируют? просто, в своих проектах постепенно перешел с (void) на (), т.к. и по тексту и визуально второе короче, и ни разу не сталкивался с засадами в этом моменте но, может, кто то реально сталкивался? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 19 февраля Опубликовано 19 февраля · Жалоба 1 hour ago, Arlleex said: "Этот ваш..." GCC - инородный компилятор, потому что нормальный компилятор выдаст сообщение о несоответствии вызова: User\main.c(80): warning: #140-D: too many arguments in function call А все потому, что если Вы используете форму декларатора определения функции с пустыми скобками, то компилятору это строгое указание, что функция не принимает аргументов (по сути, аналог int foo(void) { return 0; }). Не скажу, является ли это UB - это надо лезть в стандарт. Предположу, что должен быть UB. https://wiki.sei.cmu.edu/confluence/display/c/DCL20-C.+Explicitly+specify+void+when+a+function+accepts+no+arguments 35 minutes ago, Forger said: а вообще по практике кто-нить когда нить пытался передавать параметры в такие функции (), заранее зная, что они их проигнорируют? просто, в своих проектах постепенно перешел с (void) на (), т.к. и по тексту и визуально второе короче, и ни разу не сталкивался с засадами в этом моменте но, может, кто то реально сталкивался? Я вообще про это только в этой теме узнал от @esaulenka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 февраля Опубликовано 19 февраля · Жалоба 1 hour ago, Forger said: а вообще по практике кто-нить когда нить пытался передавать параметры в такие функции (), заранее зная, что они их проигнорируют? "Заранее знать" - это хорошее умение. Обычно большинство ошибок от невнимательности. Например, при рефакторинге убрали аргумент у функции, а в каких-то вызовах убрать забыли. Компилируется без проблем, работает, скорее всего, тоже. Но ошибка. Но сам по себе этот факт - только докопаться на собеседовании. Или уровень аргументов типа "GCC - инородный" выяснить... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 19 февраля Опубликовано 19 февраля · Жалоба 4 часа назад, dimka76 сказал: Нормально там все у GCC )))) Ну если UB в GCC - нормально, то я только за🙂 4 часа назад, dimka76 сказал: Вот пример из самого стандарта и комментарии к примеру Это объявления. Не определения. Объявление != определение, и в стандарте отдельными пунктами обозначено, что, когда и в каком случае является "функцией без параметров" и "фукнцией с неизвестным кол-вом параметров неизвестного типа". Весьма тонкий момент, который в дальнейшем перечеркнули и ввели в разряд "устаревшее, не рекомендуемое к использованию". https://stackoverflow.com/questions/693788/is-it-better-to-use-c-void-arguments-void-foovoid-or-not-void-foo#:~:text=23-,C99 quotes,-This answer aims Забавно, что меняя пустые скобки () на (void), мой компилятор уже выдет не ворнинг, а ошибку 😃 Но содержание сообщения идентично. 4 часа назад, Forger сказал: а вообще по практике кто-нить когда нить пытался передавать параметры в такие функции (), заранее зная, что они их проигнорируют? просто, в своих проектах постепенно перешел с (void) на (), т.к. и по тексту и визуально второе короче, и ни разу не сталкивался с засадами в этом моменте но, может, кто то реально сталкивался? Не сталкивался, но лучше в Сишних файлах писать void, а в C++ - забить. Береженого бог бережет. Но в целом, думаю, синтаксически можно будет создать массив указателей на такие функции (callback), и вызывать с разным кол-вом и типом аргументов. Компилятор проглотит, а вот как работать будет - хз. Плохо, наверное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 19 февраля Опубликовано 19 февраля · Жалоба 13 minutes ago, Arlleex said: Не сталкивался, но лучше в Сишних файлах писать void, а в C++ - забить. вот поэтому и забил )) 14 minutes ago, Arlleex said: Компилятор проглотит, а вот как работать будет - хз. Плохо, наверное. косяк вылезет на этапе отладки, но скорее всего сразу будет видна ошибка еще на начале применения функции, особенно если имя функции адекватно соответствует ее назначению ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvppvv 0 20 февраля Опубликовано 20 февраля · Жалоба 20 hours ago, esaulenka said: 21 hours ago, vvppvv said: И это пробовал. Нет его в IAR EW AVR 7.30.5. компилятор ругается. Это часть стандартной библиотеки: https://en.cppreference.com/w/c/types/NULL Сделайте include <stdlib.h> или include <stddef.h> Я не силён в теориях и реализациях языков. Вот попалась цитата: "Что будет если Разыменовать Nullptr? Отсюда следует, что если в вашей программе есть разыменование nullptr , то компилятор имеет право произвести любой код, никаких обязательств перед вами или гарантий нет. В лучшем случае ваша программа просто крешнется." Поэтому мне явно указаный "0" с приведением типа как-то спокойнее, чем "нулл" из какой-то библиотеки. :)) 20 hours ago, gerber said: Логично и безопасно перебрать все элементы массива и вызвать ненулевые, разве нет? Так я так и хочу. Список может быть разный по длине. Всё как со строками - перебираем, перебираем, до тех пор, пока не упрёмся в ноль. 20 hours ago, jcxz said: Может в конце списка лучше хранить не NULL, а указатель на функцию, которая и переставит указатель списка на начало? Тогда и дополнительных проверок на NULL не потребуется. Можно и так. Но тогда мы пропустим, например, посылку байта. Вместо того, чтобы функция сделала чтот-то полезное, в отпущенный ей квант времени, она просто передвинет указатель. :)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться