haker_fox 61 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 1 hour ago, tonyk_av said: Кстати, после того проекта я стал даже сишные файлы стал компилировать плюсОвым компилятором ЕМНИП, эту рекомендацию давал уважаемый @zltigo лет так 10 назад на форуме🙂 Я дополнительно пользуюсь CppCheck или/и встроенным в IAR статическим анализатором. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 14 минут назад, haker_fox сказал: ЕМНИП, эту рекомендацию давал уважаемый @zltigo лет так 10 назад на форуме🙂 Я вообще не понимаю зачем некоторые упорно продолжают компилировать в режиме си? Уже лет 15 как компилю только как с++. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба On 8/4/2023 at 11:25 AM, jcxz said: Я вообще не понимаю зачем некоторые упорно продолжают компилировать в режиме си? Уже лет 15 как компилю только как с++. Ну, сейчас начнется Чему равен sizeof('a') на Си и чему равен на С++ ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 4 августа, 2023 Опубликовано 4 августа, 2023 (изменено) · Жалоба 4 часа назад, tonyk_av сказал: я стал даже сишные файлы стал компилировать плюсОвым компилятором оффтопа немного МНОГО... прям наболело надо в ближайший понедельник взять и отменить СИ. за чем нужны коты нужен си? писать всё в с++. времена, когда код с++ был тяжелее ушли. кому-то наболел когда-то goto и он написал разгромный труд о запрете goto, у меня наболело копаться в чужом коде си, да и вообще работать в си. Вот студент, учится по специальности "микропроцессоры". Что он по выходу знает? p-n-n переходы, автоматы мили/мура, работу триггера/ключа/И-НЕ и прочей логики. Да, их (по своей учебе сужу) учат программированию. Общим приципам. Учат asm-у. Учат писать без асма сразу в машинных кодах. Но программирование у таких специалистов - это побочный продукт. Часто они становятся превосходными схемотехниками. Но иногда им приходится свои же поделки программировать. С++ их не учили, да и там высоки порог вхождения. Си тоже не учили, но там попроще и вот они начинают творить... за частую написать программу на датчик - это простой проект. Поэтому они пишут его в одного, а не в команде. Набраться навыков не у кого. И вот они пишут такой говнокод.... и пишут... потом проект становиться сложнее - какойнить контроллер... и далее далее... матереют... и продолжают писать и писать говнокод.... как это пораждается... во первых какой нить главный while() - это акын простыней. главный while() - это >10000 строк. там всё! ..... леса, реки, люди, кони.... во вторых пишут парсер на протокол - там switch() - на 1000 кейсов, в каждом кейсе может быть switch ещё на 10-20 кейсов и в них вложения for/if/for/for/switch.... ещё и отступ 8 пробелов - форматирование съезжает за экран... ну как так писать!? Ну не пишите вы функцию больше экрана. в идеале 5 строк. у вас в протоколе 300 команд - вот и 300 case. Ну сделайте std::map<>, или массив с указателем на функцию и ключом. Функция должна просматриваться одним взглядом от начало до конца без скролинга. Это улучшает читаемсоть и понимание. Опять же.... пишут в отдельном *.с файле int calc(float y).... хидеры принципиально не делают (кому они нужны, без них всё работает). совершенно в др *.с файле вызывают calc(123) - компилятор си дает ворнинг на имплицит и линкер потом всё линкует. Попробуй найди где этот calc()? Пишите хидеры. Вот проект, дали мне его, надо добавить одно окошко. По идее мне нужно написать myDialog.c и myDialog.h, в каком нибудь ОДНОМ месте подключить myDialog.h и там сделать вызов API моего диалога. Как тут делается... пишется ТОЛЬКО myDialog.с чтобы диалог собрался, нужно в др. месте добавить виджеты диалога др. в др. Т.е. в myDialog.c просто глобальная переменные - лейба, кнопка и канва. А в др. месте в глобальном ините нужно на эту канву добавить мои кнопку и лейбу. Ещё в одном месте, картинку, ещё в другом месте ещё что-то. Нужно провести изменения в 10-ти файлах. кругом через extern сделать доступные глобальные переменные, а имплицитные функции си проглотит. Спагетти. проект состоит чуть менее, чем полностью из глобальных переменных. в любом файле может быть объявлена глобальная переменная, потом в любом др *.с файле делается exten - и ВСЁ. Вы представляете!!! В каком нибудь драйвере на LСD делается переменная на текущую строку int row, или в драйвере питания переменная на текущее питание float U. а других местах делается просто extern int row и extern float U. Причем так делается не из-за незнания, а наоборот, "опытные" МК-прогеры "знают", что именно так и надо делать, надо объявлять переменную в не тела функции и в исходниках делать extern.... Я "проходил интернатуру" в команде на прогеров для ПК, меня учили - в любой программе должна быть всего одна глобальная переменная. Больше не должно быть. Сейчас понимаю - это хороший принцип. Когда говоришь автору "-У тебя тут глобальная переменная!", он в ответ "- и что? так и должно быть." А когда я устраняю ворнинг, на меня смотрят как на ненормального. Ни кто не обращяет внимания на ворнинги. Собирается?! Работает - зачем париться. У большинства МК-прогерров нет ни какой культуры написания ПО. Я не знаю как сейчас, может плотно учать в ВУЗах программированию, но опотные мк-си-прогеры - это какойто треш!!! Прежде чем писать самостоятельно ПО для МК, нужно пару лет поработать в команде с наставниками по написанию ПО. Возможно/лучше для ПК. Какую-то интернатуру устроить. Чтобы прогеру МК привили хоть какую-то минимальную культуру написания ПО. пишут int a = -3; unsigned short b = 2; if(a > b) { } Стандарт СИ оговаривает такой код, делает неявное приведение и делает сравнение. Мне когда на собеседе дали такую задачу и спросили "-В иф зайдет?", я сказал, "-Я не знаю правильный ответ, но это говнокод. Так писать нельзя и я так не пишу. Если я встречу такой код, я открою справочник, посмотрю куда преобразует СИ и сделаю ЯВНОЕ приведени типа." Они (мк-си-прогеры), не то что так пишут - они на собеседовании дают такие задачи, ожидая, чтобы претендент знал куда будет приведени и так писал. (кстати, мой ответ понравился, был защитан, я меня приняли). дальше бомблю.... IAR... какой-то идиот сделал там галочку считать char беззнаковым. По дефолту в си он знаковый. Да, компиляторы си/с++ допускают такой ключ... но, вот ты поставил эту галку. написал мегафункционал. твой функционал дернул коллега себе в код, а у него другая иде и там этой галки нет. У него будет char знаковый. Даже может код будет работать... год, два... а потом рухнет. Вообще, лучше использовать uint8_t и т.п. Но мк-прогеры самоучки. Лень писать unsigned - длинное слово, поэтому галку ставят и не парятся. А пришел новичек, подхватил проект и он даже не знает, что в си по дефолту char знаковый. Этот новичек ... 2....3 ....10 лет пишет программы и он знает, что char по дефолту беззнаковый. Использование этих галочек - это источник проблем. Ещё одна говноособенность иара... неинициализируемая переменная без явных указаний инитится нулём. Опять же... мк-самоучки пишут код... кто-то по незнанию думает что после int i; ш всегда будет 0, т.к. так должно быть в си, а кто-то это знает, и специально не инитит нулём, т.к. иар сам проинитит. И что? потом код собрали в др метсе - и прога легла. у меня был опыт, когда я в чужом проекте добавил запятую в сообщении и пересобрал. Исходный был в иар 7, я пересобрал в иар 8. Отправили программу - она переодически виснет. Не часто, но болезнено. нашел причину - использование неинициализируемой переменной. всегда явно инициализируйте переменные. 1 час назад, dimka76 сказал: Чему равен sizeof('a') на Си и чему равен на С++ ? sizeof(int) и sizeof(char). "до буквы докапались". А кто-то так пишет? Реально в жизни кто-то в коде пытается определить размер символа? Так можно написать сишнику, чтобы специально подложить мину сипипишнику. Изменено 4 августа, 2023 пользователем razrab83 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 4 августа, 2023 Опубликовано 4 августа, 2023 (изменено) · Жалоба вот ещё... прямо с пылу-жару... иногда мк-си-прогеры всётаки пишут хидеры, в которых объявляют структуры. вот пример flag.h #ifndef __SYSTEM_H__ #define __SYSTEM_H__ T_type_some *p; #endif Хидер конечна больше, я укоротил для наглядности. Это СИ. Что такое T_type_some? Это тип данных (или структура), которые определены в global.h Я включаю в свой *.с #include "flag.h" - ошибка, компилятор не знает что такое T_type_some. Подхожу к автору хидера flag.h (у него несколько десятков лет стажа), спрашиваю - WTF? Он в ответ: "-Нужно в *.с перед #include "flag.h" делать #include "global.h", и если эти инклуде поменять очерёдность, то не собрётся. " фэйспалм. Причем, он уверен, что си именно так работает и так задумано. Он считает, что в СИ очерёдность инклуде строгая, и если её не соблюдать, то код не соберётся. Нужно быть внимательным к очерёдности и правильно её делать. Я потом в его проекте как-то неаккуратно применил шланг-формат, который поправил очерёдность #include - компиялтор бедный ТАК ПОКРАСНЕЛ!!!.... чуть ли не в каждой стоке кода ошибки. Ну что это? Изменено 4 августа, 2023 пользователем razrab83 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба On 8/4/2023 at 12:42 PM, razrab83 said: Ещё одна говноособенность иара... неинициализируемая переменная без явных указаний инитится нулём. Опять же... мк-самоучки пишут код... кто-то по незнанию думает что после int i; ш всегда будет 0, т.к. так должно быть в си, а кто-то это знает, и специально не инитит нулём, т.к. иар сам проинитит. И что? потом код собрали в др метсе - и прога легла. у меня был опыт, когда я в чужом проекте добавил запятую в сообщении и пересобрал. О каких переменных идет речь ? О глобальных ? Если о глобальных, то по стандарту они по умолчанию инициализируются нулями Quote From section 3.5.7 of the C89 standard If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant. On 8/4/2023 at 12:42 PM, razrab83 said: sizeof(int) и sizeof(char). "до буквы докапались". А кто-то так пишет? memset(&i, 'a', sizeof('a')); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 45 минут назад, razrab83 сказал: Ещё одна говноособенность иара... неинициализируемая переменная без явных указаний инитится нулём. Глобальная по стандарту должна инититься нулём. Все остальные нет и иар это, самом собой, не делает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 26 минут назад, razrab83 сказал: Он считает, что в СИ очерёдность инклуде строгая, и если её не соблюдать, то код не соберётся. И он прав. В си/си++ тип должен быть известен компилятору до первого объявления переменной этого типа. А вам нужно садиться за учебники по си. 54 минуты назад, razrab83 сказал: Ещё одна говноособенность иара... неинициализируемая переменная без явных указаний инитится нулём. Очередной бред. IAR следует стандарту языка: где стандарт требует - инитит, где нет - не инитит. Если вы не знаете где должны быть проинициализированы, а где нет - это ваша проблема, а не IAR-а. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 2 минуты назад, dimka76 сказал: memset(&i, 'a', sizeof('a')); вопрос остался - а кто-то так делает? Смысл этой этой строки? 50 минут назад, razrab83 сказал: Ещё одна говноособенность иара беру слова обратно. в том проекте была локальная переменная. возможно "повезло" и в иар7 под неё выделялась память в который случайно был ноль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ericN 3 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба В 04.08.2023 в 15:34, jcxz сказал: И он прав. В си/си++ тип должен быть известен до первого объявления переменной этого типа. он не прав. формально да, всё правильно, тип должен быть известен до первого объявления переменной этого типа. Но, razrab83 привел хидер В 04.08.2023 в 15:10, razrab83 сказал: #ifndef __SYSTEM_H__ #define __SYSTEM_H__ T_type_some *p; #endif где тут до первого объявления известен тип T_type_some? Такой хидер должен быть таким #ifndef __SYSTEM_H__ #define __SYSTEM_H__ #include "global.h" T_type_some *p; #endif Не должен зависить результат сборки от последовательности include. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 4 минуты назад, ericN сказал: он не прав. формально да, всё правильно, тип должен быть известен до первого объявления переменной этого типа. Но, razrab83 привел хидер Я писал не про хидер razrab83, а про фразу сказанную его коллегой. Которую и отквотил. 4 минуты назад, ericN сказал: Такой хидер должен быть таким С этим никто не спорит. Хотя иногда некоторые компиляторы дают возможность задания общих include прямо в свойствах проекта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 9 минут назад, razrab83 сказал: а кто-то так делает? А какой смысл в этом коде заложен? Зачем count связан с sizeof('a') ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба 7 минут назад, jcxz сказал: Я писал не про хидер razrab83, а про фразу сказанную его коллегой. Коллега сказал эту фразу, именно в контексте своего хидера. Пишут хидеры, так, что для их использования перед ними нужно включать обязательно др хидер. И считают так и надо писать. Более того... вот код *.с всё в том же контексте... #include "myParams.h" #include "project.h" #include "flag.h" void funk(void) { ... } код собирается. вы видете, что тут перед #include "flag.h" нет #include "global.h", а он собирается. Как так? аказываицо в #include "project.h" включон другой инклуде, а тот ещё один.. и в тот ещё один... ещё цепочка в 10-ок и вот там #include "global.h". Человек пишет какое нибудь API... решил использовать переменную типа T_type_some - так ты либо определи её, либо сделай инклуде на неё. Пусть оно будет в *.h через 10 вложений, но, если в *.c кто-то включет твоё одно единственное #include "flag.h", у компилятора не должно возникнуть вопроса, что такое T_type_some, этот flag.h должен подтянуть всё необходимое, что он использует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба В 04.08.2023 в 15:10, razrab83 сказал: Он считает, что в СИ очерёдность инклуде строгая, и если её не соблюдать, то код не соберётся. В 04.08.2023 в 15:34, jcxz сказал: И он прав. В 04.08.2023 в 15:44, jcxz сказал: Я писал .... про фразу сказанную его коллегой. его коллега в своей фразе не прав. коллега говорил про очерёдность хидеров. в исходнике очерёдность хидеров не должна влиять на сборку, а у коллеги влияет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 4 августа, 2023 Опубликовано 4 августа, 2023 · Жалоба On 8/4/2023 at 2:18 PM, juvf said: в исходнике очерёдность хидеров не должна влиять на сборку Это по стандарту или по правилам этикета ? On 8/4/2023 at 1:35 PM, razrab83 said: беру слова обратно. в том проекте была локальная переменная. возможно "повезло" и в иар7 под неё выделялась память в который случайно был ноль. GCC в таких случаях предупреждение выдает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться