Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Косяк у Кейла
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3, 4, 5, 6
Golikov A.
Цитата
Двоечников всегда было больше... и что теперь... таблицу умножения переписывать заново... под каждого???

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

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


Цитата
Да все я понял sad.gif. Это Вы упорно нелепость "оправдать" пытаетесь sad.gif.

Да вы правы, это я зря пытался 2 раза стучать в закрытую дверь, не буду больше...

Цитата
char *function();

правильно я понимаю что функция могла принимать и не нулевой список параметров, и это получается такая служебная строчка в которой надо читать только выход?

Прикольно, я правда не застал времена без хедеров и прототипов, потому и не понимал, спасибо...
HHIMERA
Цитата(Golikov A. @ Oct 13 2015, 09:46) *
Не надо путать теплое и мягкое, я не предлагаю ухудшать проект (это равносильно изменению таблицы умножения) я предлагаю писать его более защищено и от двоечников тоже

Это и есть... из тёплого делать мягкое... вам просто это не понять... От незнаний и рождаются монстры... монстры порождают глюки... и т.д. ...
Golikov A.
не надо крайностей, я всего лишь пытаюсь сказать что

строчке вида
Код
data = (bus=get_addr()) ? data_in : -1;


предпочту блок вида
Код
bus = get_addr(); // получаем адрес
if(bus !=0) //если не 0
   data = data_in; //забираем данные
else //для 0 адреса
  data = -1; //ставим флаг - 1


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

Теперь приведите вы пример когда такой подход рождается монстра.... Только не надо про строчки на экран, сейчас можно по 2 монитора и огромного размера....

scifi
Цитата(Golikov A. @ Oct 13 2015, 10:05) *
предпочту блок вида
Код
bus = get_addr(); // получаем адрес
if(bus !=0) //если не 0
   data = data_in; //забираем данные
else //для 0 адреса
  data = -1; //ставим флаг - 1

Посыл правильный, но с комментариями накосячили. Ну вот зачем писать "data = -1; //ставим флаг - 1" и т.д. и т.п.??? Одно из первых правил комментирования: не комментируйте то, что и так понятно (даже двоечнику).
HHIMERA
Цитата(Golikov A. @ Oct 13 2015, 10:05) *
когда такой подход рождается монстра....

Одна строчка... или несколько??? Чудесно... когда незнания прикрываются "для лучшего понимания"...
Ещё веселей... когда эмбеддерство сравнивают с работой кассира... Поменяйте их местами... Эмбеддер спросит... "Куда здесь подключиться, мне шрифт на чеке не нравится?"... кассир спросит... "Что нажать, чтобы выехал чек с уже готовой программой?"...

Цитата(scifi @ Oct 13 2015, 10:21) *
Одно из первых правил комментирования: не комментируйте то, что и так понятно (даже двоечнику).

Просто... Одно из первых правил... двоечники не знают правил...
zltigo
QUOTE (Golikov A. @ Oct 13 2015, 09:46) *
правильно я понимаю что функция могла принимать и не нулевой список параметров, и это получается такая служебная строчка в которой надо читать только выход?

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


QUOTE (Golikov A. @ Oct 13 2015, 10:05) *
Теперь приведите вы пример когда такой подход рождается монстра....

Так Вы уже и сами привели пример урода sad.gif. Вместо четкого и быстровоспринимаемого выражения нагородили сложное, которое быстро не воспирнимается, восприятие которого читающим зависит от форматирования, да еще утопили все это в ненужных комментариях отвлекажщих внимание читающего. Во всем этом буйстве букв, тем не менее остался отразчик классического дерьма:
-1
Может комментарии что-то прояснят?
//ставим флаг - 1

Потрясающе понятно sad.gif

Все это вместо того, что-бы написать одну строчку типа:

data = get_addr() ? data_in : END_DATA;










ViKo
Я выбираю первый вариант, что выдал Golikov, однозначно. Мне в нем все понятно, красиво, компактно. Комментарий написал бы перед строчкой, что-нибудь "прочитать шину".
scifi
Цитата(zltigo @ Oct 13 2015, 11:10) *
data = get_addr() ? data_in : END_DATA;

Минуточку! Там ещё было присваивание перед сравнением. А без присваивания я бы и сам так написал. ИМХО, тех, кто не понимает "?:", нельзя подпускать к клавиатуре.
Golikov A.
Цитата
Посыл правильный, но с комментариями накосячили. Ну вот зачем писать "data = -1; //ставим флаг - 1" и т.д. и т.п.??? Одно из первых правил комментирования: не комментируйте то, что и так понятно (даже двоечнику).

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

Цитата
Минуточку! Там ещё было присваивание перед сравнением

Именно меня бесят конструкции вида if(data = funct())
то есть вызываем функцию, ее результат присваиваем, и сразу используем в виде условия...

?: - хорошо, а когда это
? : ? : ? :....
да еще чтобы компактнее было пробелы повырезают....



Цитата
data = get_addr() ? data_in : END_DATA;

Кстати вот мы только что наблюдали типичную ошибку компактного стиля.
Человек с колосальным опытом, взглянув на его любимый стиль
Цитата
Вместо четкого и быстровоспринимаемого выражения нагородили сложное, которое быстро не воспирнимается,

и быстро воспринял конструкцию НЕ правильно.

так что дальше можно уже писать что угодно. Оно в жизьни именно так и бывает...



Цитата
Ну где-то так. В этом выражении () только для того, что-бы обозначить

Понятно, я такое реально не застал, познавательно, спасибо!
zltigo
QUOTE (scifi @ Oct 13 2015, 11:26) *
Минуточку! Там ещё было присваивание перед сравнением. А без присваивания я бы и сам так написал. ИМХО, тех, кто не понимает "?:", нельзя подпускать к клавиатуре.

Там было
CODE
bus = get_addr(); // получаем адрес
if(bus !=0) //если не 0
   data = data_in; //забираем данные
else //для 0 адреса
  data = -1; //ставим флаг - 1

Я не вижу никакого другого использования bus для чего либо.
Еще вопросы?

QUOTE (Golikov A. @ Oct 13 2015, 11:32) *
Именно меня бесят конструкции вида if(data = funct())то есть вызываем функцию, ее результат присваиваем, и сразу используем в виде условия...

Это все от незнания языка sad.gif. Эллочка людоедка тоже владела небольшим подмножеством языка и ее тоже бесило, и на все ей непонятное отвечала что-то вроде "хаимишь парниша" sad.gif.
В языке абсолютно четко расписано что является результатом операции присваивания и порядок выполнения операций. Какие это дает поводы бесится, даже если написано
CODE
a = b = c = d;

?
Golikov A.
Кто-то обкакался и пытается сохранить лицо... ок продолжим

Цитата
Я не вижу никакого другого использования bus для чего либо.

тогда вы тоже написали чушь
Код
data = get_addr() ? data_in : END_DATA;

потому что я не вижу определения END_DATA, и не припоминаю такого ключевого слова в С, более того я хотел на шине выдать флаг -1, как флаг ошибочного адреса, а не как флаг окончания данных.... wink.gif

у меня кусок выдранный из контекста и бас используется чуть ниже ключевым образом - гипотетически, а вы даже переменные не определили... тоже мне гуруsm.gif
scifi
Цитата(zltigo @ Oct 13 2015, 12:03) *
Я не вижу никакого другого использования bus для чего либо.

Ну не видите - и ладно. С кем не бывает?

Цитата(zltigo @ Oct 13 2015, 12:03) *
Еще вопросы?

Вообще, мне кажется, Вы излишне возбуждены, нет?

Эй, модераторы, пора бы уже зарубить этот топик. Он давно превратился в какое-то соревнование по писькометрии и/или метанию какашек (не будем показывать пальцем). В других топиках карающий меч разит за прыжок на месте, а тут такое laughing.gif
zltigo
QUOTE (Golikov A. @ Oct 13 2015, 12:05) *
потому что я не вижу определения END_DATA, и не припоминаю такого ключевого слова в С, более того я хотел на шине выдать флаг -1, как флаг ошибочного адреса, а не как флаг окончания данных.... wink.gif

Хотите сказать, что #define Вас тоже бесят?
Это уже Ваше дело, как назвать флаг. Главное, что не должно быть -1 да и еще с издевательским коментарием типа // это -1
Вот Вы сейчас у меня увидели абсолютно произвольное название флага и СРАЗУ поняли, что он ОЗНАЧАЕТ и присваивается что-то неправильноe. А я из Вашего -1 не смог понять НИЧЕГО.
А если-бы у Вас было что-то типа
CODE
#define DATA_ADDR_ERROR (-1)

То все было-бы ясно.
А так, вкупе со всеми ненужными выражениями и комментариями - обыденный образчик говнокода sad.gif. Очень жаль, но это так sad.gif

QUOTE
Ну не видите - и ладно. С кем не бывает?

Ну если "ладно", то к чему вообще была Ваша предыдущая реплика, а если уж ее написали, то уж потрудитесь объясниться.

QUOTE (scifi @ Oct 13 2015, 12:11) *
Вообще, мне кажется, Вы излишне возбуждены, нет?

Для этого у меня есть какие-то причины?
GetSmart
Цитата(zltigo @ Oct 11 2015, 23:38) *
Удивился. Проверил.
...
ругается:
Error[Pa045]: function "dummy" has no prototype

Уже указали почему.

Неявным логичнее было делать void. Не вижу грабли, т.к. объявления функций делаются всегда вне тел функций. И для явного указания типа результата функции void удачно подходит. И его смысл, как и других типов, в указании типа одного объекта. Что касается применения в коде (void) в качестве преобразования типа rvalue, то хз какой смысл этой конструкции должен быть в идеальном Си. Встречал его в FatFS и там он точно не вызывал чтение только что объявленной локальной неволатильной переменной (или аргумента функции, не помню точно). Скорее всего маскировал какой-то варнинг. Увидев такое в первый раз без чтения стандарта или инета догадаться "что хотел сказать автор" было невозможно.

Наиболее ключевой момент в указании списка аргументов функции - указать пустое множество, совместимое с данным контекстом. Совместимое, если множества применялись бы и для других целей. Скобки после идентификатора в процессе объявления объекта указывают компилятору, что объявляется функция. Пустое множество в этом контексте семантически ближе всего к пустым скобкам, если нет специального ключевого слова или конструкции пустого множества. "Пустой" тип (можно перевести по-разному) не является пустым множеством, как навязывается стандартом. IAR в этом плане с настройками по-умолчанию позволяет программистам писать свои программы без семантической кривизны.

Цитата(den_po)
Неявное объявление функции при первом использовании - вот, наверное, самое отвратительное в сях.

Всё зависит от момента в эволюции языка, в котором делается такая оценка. Вызов функции из другого объекта компиляции без наличия прототипа, то есть всех типов и поэтому кол-ва всех аргументов конечно неоднозначен. В этом случае ошибку разумнее всего выдать.
zltigo
QUOTE (GetSmart @ Oct 13 2015, 21:12) *
...писать свои программы без семантической кривизны.

https://www.youtube.com/watch?v=L4Jsij6eLsA
Мне с учетом предыстории развития языка все понятно и принятые компромиссы вполне разумны. Для удовлетворения амбиций можете начинать создавать собственый совершенно "правильный" язык. Ну или заведите в качестве личного компромисса себе чего нибудь типа
#define void_set void
GetSmart
Цитата(zltigo @ Oct 14 2015, 00:58) *
Мне с учетом предыстории развития языка все понятно и принятые компромиссы вполне разумны.

Не могу смотреть ютуб и вообще видео. Напишите словами.

Может заодно проясните выбор запятой в качестве разделителя аргументов. Т.к. в этом тоже есть двухсполовинная неидеальность. Очевидная в постоянном указании типа нового аргумента после каждой запятой. Что и не очень удобно и явно синтаксически отличается от объявления переменных вне заголовка. Это полтора. И ещё одна кажись какая-то грабля из-за использования comma в качестве оператора в коде функций. Обсуждалось год-три назад. Точка с запятой там "ложилась" очень удачно. Похоже конечно на for(a;b;c), но икс знает хорошо это или плохо. Опять всплывёт какой-нить исторический подвох. Псевдобонус в вырезании имён аргументов из прототипов равноценен по трудозатратам замене имён аргументов при разделении их точкой с запятой. Но этот оверхед трудозатрат скорее бесполезен, т.к. компилятор должен встречая прототип делать то же самое самостоятельно.
zltigo
QUOTE (GetSmart @ Oct 14 2015, 01:00) *
Не могу смотреть ютуб и вообще видео. Напишите словами.

Там мнение Остапа Бендера о подобной проблеме.
GetSmart
Цитата(zltigo @ Oct 14 2015, 00:58) *
Мне с учетом предыстории развития языка все понятно и принятые компромиссы вполне разумны. Для удовлетворения амбиций можете начинать создавать собственый совершенно "правильный" язык. Ну или заведите в качестве личного компромисса себе чего нибудь типа
#define void_set void

Этот дефайн что-то вроде "ничего не слышу, ничего не вижу".

Цитата(zltigo)
Тогда, пожалуйста, просто подумайте, как до введения стандарта с прототипами, я должен был написать вызов функции находящейся в другом объекте компиляции и, например, возврашаюшей указатель на char. Прототипов нет. Написали вызов функции, а что она возвращает компилятору неведомо, ну точнее ведомо, что по умолчанию int. А если не int? Нужно как-то декларировать возвращаемое значение. Вызов компилятор по известым ему типам аргументов сделает, а что возвратят ему неведомо. Посему так:

Кривизна из-за разной интерпретации пустых скобок в разном контексте глаз мозг режет. В декларациях их нагрузили неизвестностью параметров. И вместе с этим в заголовке и при вызове они означали отсутствие параметров. Если разработчик планировал вызывать функцию, то знать лучше и результат и типы аргументов. Основания для отбрасывания аргументов не озвучены. Про вариант передачи аргументов через стек и удаление из вызывающей стороной я в курсе, но это не тянет на основания удаления аргументов из декларации, т.к. кроме их кол-ва нужно знать их типы для конвертации rvalue. Для вызова функций из своего модуля можно было сверить и заругаться, а из другого модуля, если неизвестно какого типа у неё аргументы и во что конвертировать rvalue, то. невозможно вообще скомпилить "объект компиляции" и с самого начала была видна нужность указания аргументов. Игра в грабли кого-то с кем-то.

А сейчас в чём например грабля, если компилятор будет иметь опцию (как require prototypes и др.) задающую по-умолчанию смысл пустых скобок в прототипах равный отсутствию аргументов и выдающую варнинг, если функцию вызывают с какими-то аргументами? В этом режиме не обломается скомпилить даже комбинацию с древними исходниками. Эта опция даже к стандарту не обязана относиться. Могу только повторить - хвала ИАРу, который не идёт на поводу у недоброжелателей языка.

В соседней ветке ещё упоминают объявления функций внутри typedef. Там тоже (мне) не понятно как интерпретируется объявление, как прототип или как декларация. Опять двусмысленность, т.к. судя по теме можно и с void и с пустыми скобками в Кейле. Должен был быть разрешён только один вариант. Если НЕИСКУШЁННЫЙ граблями программист будет ломать голову о том, что хотел сказать автор и будет много шансов ошибиться, то это всегда будет на совести разработчиков.
Непомнящий Евгений
Цитата(Golikov A. @ Oct 13 2015, 10:05) *
предпочту блок вида
Код
bus = get_addr(); // получаем адрес
if(bus !=0) //если не 0
   data = data_in; //забираем данные
else //для 0 адреса
  data = -1; //ставим флаг - 1


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


Комментировать каждую строку - вы серьезно? Если кто-то не знает язык, то его надо просто выучить. Комментарии нужны там, где решение неочевидно из кода, но комменты вида
Код
x = 0; // положим в x 0

- это просто мусор. Комментировать надо алгоритм, какие-то блоки кода. Но делать из программы учебник по языку - зачем?


Цитата(GetSmart @ Oct 14 2015, 04:27) *
А сейчас в чём например грабля, если компилятор будет иметь опцию (как require prototypes и др.) задающую по-умолчанию смысл пустых скобок в прототипах равный отсутствию аргументов и выдающую варнинг, если функцию вызывают с какими-то аргументами? В этом режиме не обломается скомпилить даже комбинацию с древними исходниками. Эта опция даже к стандарту не обязана относиться. Могу только повторить - хвала ИАРу, который не идёт на поводу у недоброжелателей языка.

Компилируйте новые исходники в режиме С++ и будет вам счастье. Конечно хидеры 20-летней давности придется поправить, но неужели их так много?
ViKo
Интересно, кто-нибудь занимается разработкой нового стандарта на язык C? Или он уже достиг предела совершенства. Мне вот C++ кажется неоправданно сложным. Знаю, гуру скажут, от "дремучести" моей рождаются монстры. Чего не хватает в C - например, определения функции внутри функции... сам не знаю, чего... но что-то не так. Хочу простого, но качественного. Те же прототипы - зачем они, если можно просмотреть все исходники проекта, и составить список определений функций автоматически?
Непомнящий Евгений
Цитата(ViKo @ Oct 15 2015, 09:46) *
Интересно, кто-нибудь занимается разработкой нового стандарта на язык C? Или он уже достиг предела совершенства.

Стандарт периодически обновляется. В последнем - атомики появились, еще что-то. Не слежу пристально

Цитата
Мне вот C++ кажется неоправданно сложным. Знаю, гуру скажут, от "дремучести" моей рождаются монстры.
Чего не хватает в C - например, определения функции внутри функции... сам не знаю, чего... но что-то не так. Хочу простого, но качественного.

Дык используйте подмножество С++, и будет вам счастье. Никто не заставляет использовать все и сразу.

Код
void func(int a, int B) {
  int c = 0;
  auto localFunc = [&](int x) {
    a += x;
    b -= x;
    c *= x;
  };

  localFunc(15);
  localFunc(25);
}


Цитата
Те же прототипы - зачем они, если можно просмотреть все исходники проекта, и составить список определений функций автоматически?

Раздельная компиляция жеж...
zltigo
QUOTE (ViKo @ Oct 15 2015, 09:46) *
Те же прототипы - зачем они, если можно просмотреть все исходники проекта, и составить список определений функций автоматически?

1) Библиотеки и объектники тоже sm.gif sm.gif sm.gif?
2) При работе с кем-то пока не получите полные исходники - фиг откомпилируете свой кусок?
3) Хотите - просматривайте, составляйте. Как будете "составленый" список компиятору предавать? Прототипы это механизм предачи описания, который должен быть по любому. А окуда Вы это описание возьмете - дело не принципиальное.



QUOTE (Непомнящий Евгений @ Oct 15 2015, 09:52) *
Дык используйте подмножество С++, и будет вам счастье. Никто не заставляет использовать все и сразу.

Именно так. Начиная я писать на С++, а не на Cи, так-что на PC как-то после ухода на Cи в основной массе работ, сполз постепенно на "псевдо Си" - Си, но под плюсовый компилятор.

GetSmart
Моё мнение о Си.

Переменная-указатель на функцию с неизвестными аргументами, как и аналогичная декларация, есть грабля. Пустые скобки при её объявлении логично интерпретировать как отсутствие аргументов. При вызове её с какими-то аргументами выдавать варнинг, аналогично вызову функции через декларацию. Варнинг при вызовах через декларации более чем уместен из-за неизвестности типа аргументов при конвертации rvalue. Даже опция его включения лишняя. На заре эволюции разрешили криминал, который давно надо было плавно заблокировать.

Пример:

объявление глобальной или локальной переменной:
void (*Func)(стандартные правила для прототипов/деклараций);

в коде функций:
Func = (void (*)())FuncAddr;

Интерпретация пустых скобок в смысле неизвестности списка аргументов удачна в конструкции преобразования типа целочисленного rvalue, интерпретируемого как адрес функции. Наделяя получившееся rvalue универсальностью в дальнейших конвертациях. Но попытку вызова функции через rvalue с таким типом лучше интерпретировать как ранее описано из переменной.

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

Т.к. текстовый препроцессор тоже разгребает список передаваемых ему аргументов, то и там могут быть какие-то грабли с "(void)", "()", неоднозначностью толкования и разными контекстами. И вообще, корректностью стандарта.

Про void в скобках в списке аргументов ничего хорошего не добавлю sm.gif

Цитата(GetSmart @ Oct 11 2015, 18:28) *
По поводу пустых скобок в for() ошибся, т.к. никогда его не использую, ... for(;;)

Уточняю. В таком виде.
ViKo
Цитата
По поводу пустых скобок в for() ошибся, т.к. никогда его не использую, ... for(;;)

У меня в коде есть даже for( ; ; ) ; rolleyes.gif
GetSmart
Цитата(zltigo @ Oct 14 2015, 00:58) *
Мне с учетом предыстории развития языка все понятно и принятые компромиссы вполне разумны. Для удовлетворения амбиций можете начинать создавать собственый совершенно "правильный" язык.

Компромисс чего с чем? В скобках видна только лишняя сущность, вроде червя. Хочу понять, но не хватает информации. Перечитал все посты здесь. В разных контекстах интересно. В случае отсутствия необходимости наследования исходников есть какие-то недостатки? Или единственный недостаток в том, что компилятор будет ругаться на криминальные вызовы через декларации в древних исходниках?

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

Если у вас есть корпоративные правила, если у вас есть ГОСТы на ПО и прочее, то писать надо как предписывают правила.

Если вы работаете в команде и у вас есть стиль, то писать надо как предписывает стиль, чтобы команде было удобно работать....

Не надо думать что как и почему, зачем в стандарте. Выберите свой путь из допустимых и вперед....
GetSmart
Цитата(Golikov A. @ Oct 17 2015, 11:10) *
Если вы работаете один, на вашем коде не лежат риски жизни, вам все понятно и все знаете как кое кто, то писать можете как угодно.

У меня много кода написано без (void) и ИАР всегда его правильно компилировал. Попытка компиляции одного из них в Кейле выдала варнинг, который я здесь обсудил. После таких угроз в ненадёжности мне любопытно, насколько они обоснованны. С секретными стандартами не знаком. Укажите, в чём неоднозначности толкования. Увод внимания с очевидно рискованных операторов вроде comma на ложную страшилку - типичный приём мошенничества.

Если zltigo не прояснит заданный ему вопрос, а он умеет конструктивно аргументировать когда есть чем, то можно делать вывод, что нечем. Одновременность ввода void в стандарт для типа функции и для списка аргументов, которым он пытается "отбиться", пока тянет только на маскировку бесполезности/вредности второго нововведения. Или ещё можно предпологать (ака делать вид), что он знаком с военной тайной, которую простым смертным знать не полагается.
Golikov A.
конкретно про void
как я понял в каких то дремучих годах, не было прототипов функций.

и если вам надо было вызвать в коде функцию из другого файла (условно), да при этом она возвращала не int, то чтобы обозначит этот возвращаемый тип ввели то что тут назвали декларацией функции, то есть есть у нас

Код
char MyFunc(int a, char d)
{
  .....
}


мы хотим ее вызвать где-то в другом файле, и у нас нет прототипов, то есть нельзя подключить заголовочный файл с описанием
char MyFunc(int a, char d); Тогда мы в начале этого файла где хотим вызвать пишем
char MyFunc(); - то есть смысл указать что MyFunc возвращает char, и потому разрешили скобки оставить пустыми, то есть не важно что она принимает важно что она возвращает.

Потом стандарты поменялись и ввели прототипы и как я понимаю для большей строгости решили разделить
char MyFunc(); которая принимает кучу параметров и запись есть декларация возвращаемого значения и
char MyFunc2(); которая на самом деле не принимает никаких значений, и потому в прототипах вторая указывается как
char MyFunc2(void);

Нужно ли тянуть все эти атавизмы до С89, когда уже и С99 не последний я не знаю. Сам я пишу для функций не принимающих значения явным образом void в скобках. Потому что это явно обозначает мои желания при объявлении функции. Текста мне, как и ударов по кнопкам не жалко, а может быть кого-то это спасет.

Объявите где-то еще такую функцию, но с параметрами и сразу получите об этом сигнал. В то время как char MyFunc(); может трактоваться и как функция без параметров, так и функция с произвольным числом параметров. То есть это расширение в сторону большей определенности, чтобы не было что я думал будет так, а компилятор подумал что будет эдак.
Хотя кто-то считает это малодушием и предлагает наизусть выучить как подумает компилятор, самому запомнить и тролить этим новичков, постоянно используя в коде всякие неоднозначные вещи...
GetSmart
Буду считать, что компромисс с микробами.

---------------

Проверил на ИАР. Он не выдаёт даже ремарки на вызов через декларацию с заданием любого кол-ва арументов.

C FatFS и "(void) переменная" напутал. Это был NXP UsbHostLite. Там (void) применялся к аргументу функции (указатель но волатил-массив) без его использования "(void) arg;".

В исходниках EHCI тоже встречается преобразователь типа - (void), но стоит перед некоторыми вызовами некоторых (в т.ч. статик) функций, возвращающих значения. Фунции, судя по логике программы, вызываются. Значение отбрасыватся. Но и без (void) оно должно отбрасываться без замечаний компилятора. Вызов этих функций там есть и без (void) с отбрасыванием результата. Что же хотел сказать автор?

Напоминает крики о помощи подневольных программистов sm.gif
Непомнящий Евгений
Цитата(GetSmart @ Oct 17 2015, 22:46) *
Проверил на ИАР. Он не выдаёт даже ремарки на вызов через декларацию с заданием любого кол-ва арументов.


Так компилируйте в режиме С++, в чем проблема-то?
zltigo
QUOTE (GetSmart @ Oct 17 2015, 22:46) *
В исходниках EHCI тоже встречается преобразователь типа - (void), но стоит перед некоторыми вызовами некоторых (в т.ч. статик) функций, возвращающих значения. Фунции, судя по логике программы, вызываются. Значение отбрасыватся. Но и без (void) оно должно отбрасываться без замечаний компилятора. Вызов этих функций там есть и без (void) с отбрасыванием результата. Что же хотел сказать автор?

Я тоже такое видел не раз. Гипотетически как-то может помочь оптимизации при встаивании static функции. На деле просто чушь с точки зрения компилятора. Но писателю исходников может так нравится.

den_po
Цитата(zltigo @ Oct 19 2015, 09:59) *
На деле просто чушь с точки зрения компилятора.

А может, это обход ругани каких-нибудь особо дотошных статических анализаторов кода?
zltigo
QUOTE (den_po @ Oct 19 2015, 10:02) *
А может, это обход ругани каких-нибудь особо дотошных статических анализаторов кода?

Как вариант. Но лично я встречал сие весьма хаотически разбросанное по исходнику. Могу найти образчик, ибо с месяц назад вычитывал один исходник от Jennic - помнится там сие встречалось. Сам исходник был такой, что хоть святых выноси sad.gif, но являлся частью вынуждено вынесенного на всеобщее обозрение стека и действительно вполне мог писан с соблюдением каки-то формальных требований.




scifi
Цитата(GetSmart @ Oct 17 2015, 22:46) *
В исходниках EHCI тоже встречается преобразователь типа - (void), но стоит перед некоторыми вызовами некоторых (в т.ч. статик) функций, возвращающих значения. Фунции, судя по логике программы, вызываются. Значение отбрасыватся. Но и без (void) оно должно отбрасываться без замечаний компилятора. Вызов этих функций там есть и без (void) с отбрасыванием результата. Что же хотел сказать автор?

Автор хотел сказать, что, дескать, я не забыл, что функция возвращает значение, просто я его нарочно игнорирую. К тому же некоторые компиляторы могут выдавать предупреждение "возвращаемое значение не используется", и приведение к void помогает подавить это предупреждение.
Tarbal
Цитата(zltigo @ Aug 28 2015, 19:02) *
В бессмысленности получившегося выражения. По этой причине прилично-бы выдать warning. IAR-у можно включить. Но у большинства - нет sad.gif

Вообще-то этот трюк позволяет энкапсулировать макрос. И еще мне когда-то надо было избежать goto и данное решение легко позволяет заменить его на break.
zltigo
QUOTE (Tarbal @ Oct 20 2015, 15:35) *
Вообще-то этот трюк позволяет энкапсулировать макрос. И еще мне когда-то надо было избежать goto и данное решение легко позволяет заменить его на break.

Готов рассмотреть КОНКРЕТНО обе Ваших "проблемы". Дайте этих два кусочка исходников и рассмотрим необходимость тиражирования конкретных трюков.
Golikov A.
вот типа того

Код
...
if (cond1)
   goto end
....
if(cond2)
  goto end
....
:end
....
...


вот такой код, надо не трогая структуру не трогая то что под ... переписать чтобы не было goto, а логика работы осталась прежней...
zltigo
QUOTE (Golikov A. @ Oct 20 2015, 16:50) *
вот типа того

CODE
...
if (cond1)
   goto end
....
if(cond2)
  goto end
....
:end
....
...


вот такой код, надо не трогая структуру не трогая то что под ... переписать чтобы не было goto, а логика работы осталась прежней...

Для чего "надо"?
А для чего вообще надо было писать это дерьмо с goto, потом для неведомо чего усугублять оставляя изначальное дерьмо но без goto следуя дебильному лозунгу "goto вредно"?
А написать сразу по человечески что мешало? Ну а способов, как оставить "похоже" множество. Самые безобидные:
CODE
static void dummy(void)
{
if (cond1)
   return;
....
if(cond2)
  return;
....
}


CODE
...

for(;; )
{
if (cond1)
   break;
....
if(cond2)
  break;
....
break;
}



Из серии наворотить дальше, наряду с Вашим любимым и "незаменимым" while{}do(0)
можно писать чего угодно, да хоть switch(0){}

Только нафига sad.gif
Golikov A.
Надо бывает много для чего, ну и чем for(;;) {break} или switch(0){} лучше while{}do(0), ну кроме того что вы его лично не любите?



scifi
Цитата(Golikov A. @ Oct 20 2015, 21:14) *
Надо бывает много для чего, ну и чем for(;;) {break} или switch(0){} лучше while{}do(0), ну кроме того что вы его лично не любите?

Не буди лихо, пока оно тихо crying.gif
zltigo
QUOTE (Golikov A. @ Oct 20 2015, 21:14) *
Надо бывает много для чего, ну и чем for(;;) {break} или switch(0){} лучше while{}do(0), ну кроме того что вы его лично не любите?

1) Не надо было вообще ТАК писать, а написав, уж точно не страдать фигней и не преписывать неведомо зачем. Это понятно?
2) for(;;){breaк} абсолютно естественно без всяких натяжек. while... ненужный трюк со скользким условием на который нормальный компилятор выдает warning. "Личная нелюбовь" нипричем. Сколько раз будете спрашивать одно и то-же? Не надоело? Ответ давался. switch... примерно те-же яйца в профиль, что и while...
Golikov A.
1) бывают разные ситуации и условия, и иногда надо делать не что хочется. Это понятно?

2) цикл do{}while(условие) стандартом определен? - определен. 0 - как ложное условие стандартом определен? - определен. Значит никакого нарушения стандарта нет.

То что ваш любимы компилятор выдает на это варнинг ничего ровным счетом не значит, кроме того что авторы компилятора посчитали эту конструкцию более редкой и предупредели об этом, просто указав вам на возможную ошибку. Ровно как то что он не выдает варнинг на for(;;), потому что эту конструкцию авторы посчитали более часто употребимой. И ВСЕ!!!

Я вот тут недавно вообще столкнулся с проверкой кода по формальным признакам и узнал много много новогоsm.gif о том как надо и как не надо писать, и в этой области нарушения - это не варнинги, это ерроры, и писать надо как предписывают правила, а не блаж компилятора. Лично добавил несколько определений которые теперь висят у меня варнингом в среде, потому что иначе это была ошибка на формальной проверке и ничего не поделаешь....

Так что пока вы не покажете строчку стандарта где написано что конструкция do{}while(flase) запрещена, или выполниться не 1 раз, или что 0 под while будет трактован как-то еще кроме как ложь, все ваши аргументы будут лишь вашим личным субъективным мнением. Которое истинна только для васsm.gif
zltigo
QUOTE (Golikov A. @ Oct 20 2015, 22:11) *
и узнал много много нового...

остается только надеяться, что это не последнее новое, что Вы узнаете и то, что в процессе "узнавания" сможете сохранить способность самостоятельно думать.
Начать попытки думать можете с объясния того факта, что мне известы, как минимум, три компилятора выдающих предупреждение на всякие while(1) и ни одного компилятора не понимающего, в отличие от Вас, for(;;). Это раз. А так-же того факта, что нет никакой необходимости использовать все эти while(1) и do(0).
Golikov A.
Я могу прямо сейчас создать корпоротивное правило запрещающее использовать for(;;) и предписывающее использовать while(1). Более того я могу написать свой компилятор который будет это поощрять. И что фор станет хуже вайла?

Также я могу вам привести пример того когда это необходимо.

Вы трактуете мир на основании вашего несовершенства. Вы уверены что все дураки, кроме вас, а это между прочем грех и гордыня. С чего вы взяли что ваша старческая истерика лучше чем мысли других людей? Вы ведь не только мне написали в вызывающем тоне про думать и тому подобное? Попробуйте послежовать своему совету и начать думать.
Tarbal
Цитата(zltigo @ Oct 20 2015, 20:34) *
Код
...

for(;; )
{
if (cond1)
   break;
....
if(cond2)
  break;
....
break;
}

Не помню деталей, но надо было, чтобы точка с запятой требовалась в конце да и ваш вечный цикл требует не забыть брейк в конце. Вот это уже как раз кривая натяжка.
zltigo
QUOTE (Golikov A. @ Oct 21 2015, 01:24) *
Я могу прямо сейчас создать корпоротивное правило запрещающее использовать for(;;)

Вы уже создали себе в голове "правил" sm.gif. Ну и что? Задача убедить остальных жить по Вашим правилам. Та же история с языком и компилятором который Вы грозитесь написать.
QUOTE
Также я могу вам привести пример того когда это необходимо.

До сих пор этого здесь никто не смог, включая Вас.
QUOTE
Вы трактуете мир на основании вашего несовершенства. Вы уверены что все дураки, кроме вас, а это между прочем грех и гордыня. С чего вы взяли что ваша старческая истерика лучше чем мысли других людей? Вы ведь не только мне написали в вызывающем тоне про думать и тому подобное?

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

QUOTE (Tarbal @ Oct 21 2015, 01:31) *
Не помню деталей..

Впомните - расскажете sm.gif
QUOTE
и ваш вечный цикл требует не забыть брейк в конце.

А другой "не забыть" while(0) после sm.gif где весь перечень того, чего нельзя забывать при программировании sm.gif
IgorKossak
Удалил крайние сообщения с обсуждениями личных качеств пользователей.
При рецидиве начну банить.
Модератор
GetSmart
Чужие исходники это кладезь хитровывертов.
файл inflate.c
Код
#define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; })


в коде

NEXTBYTE(); /* Get timestamp */
NEXTBYTE();
NEXTBYTE();
NEXTBYTE();

(void)NEXTBYTE();
(void)NEXTBYTE();

magic[0] = NEXTBYTE();

На каком языке это написано? Внутри круглых скобок можно использовать фигурные?
uch вероятно объявлено как unsigned char.

Как мне понимается, препроцессор заменит текстовым содержимым дефайна все заголовки NEXTBYTE(), встречающиеся в исходном тексте.

Во-первых, разве в Си можно узнать значение локальной переменной вне блока, в котором она объявлена?
Во-вторых, разве точка запятой, завершающая оператор/statement не отбрасывает значение rvalue?

---------------

Что на вызовы через декларации не выдаются даже ремарки по терминологии ИАРа - это однозначно сговор.
zltigo
QUOTE (GetSmart @ Oct 24 2015, 11:35) *
...кладезь хитровывертов.

Нет. Это кто-то тупо мучал компилятор до тех пор пока что-то не "заработало" а остальное потом "отладит".
QUOTE
На каком языке это написано?

Олбанский?
Непомнящий Евгений
Цитата(GetSmart @ Oct 24 2015, 11:35) *
На каком языке это написано? Внутри круглых скобок можно использовать фигурные?
Во-первых, разве в Си можно узнать значение локальной переменной вне блока, в котором она объявлена?
Во-вторых, разве точка запятой, завершающая оператор/statement не отбрасывает значение rvalue?


Это расширение gcc такое.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.