Когда мы делаем git blame в каком-нибудь огромном файле, в который каммитили все, кому не лень, найти изменения по какой-то конкретной фигне может быть довольно долго.
+ даже зная, кто и каким каммитом добавил функционал, не всегда можно понять, в рамках какой задачи это было сделано. (не все и не везде указывают).
Да и в любом случае, просто вбить заранее указанный номер задачи в трекер будет в разы быстрее, чем сначала искать «кто, где и зачем».
По поводу того, что комментарии не поддерживают — не соглашусь.
Я бы посмотрел на того, кто бы взялся сопровождать тот же bb, не будь он так хорошо задокументирован)
Если комментарии не нужны, то почему так много рекомендаций из самой различной литературы и интернета отмечают умение грамотно писать комментарии одним из правил хорошего тона?
Мой ответ к комменту выше частично актуален, но предположу:
Обмен сообщениями на сокетах тесно связан со структурой sockaddr_in. В один из ее экземпляров можно записывать адрес клиента, который пытается подключиться.
Если этот вариант не проканает, то можно воспользоваться RAW-сокетами — тогда можно будет распарсить сырой пакет полностью и посмотреть заголовки.
После этого — сравнить сертефикаты.
Про сертификат до этой статьи я был ни сном, ни духом :)
Ну да, http-сервер — это «простое сетевое приложение», что в этом удивительного?
Последние пару месяцев я моими тасками было ковыряться в сорцах udhcpc и udhcpd, расширяя его функционал.
После всего этого то, что представлено тут, воспринимается очень просто :)
Например, я вообще не писал ботов.
Теперь мне стало ясно, как работать с апи, предоставляемым телеграммом.
Я был приятно удивлен тем, что можно оформить это в виде простого сетевого приложения (у меня уже целая библитека функций для приложений на сокетах).
В самом начале статьи автор предупредил, что не является профессиональным си-программистом.
Поэтому, кмк, профит данной в статьи именно в алгоритме действий.
У тех, кто в первый раз с этим столкнулся перед глазами будет рабочий пример:)
Я прочитал ваш комментарий.
Да, я не прав. Многопоточное приложение тут не при чем, компилятор в состоянии отслеживать изменения переменных в потоках.
А вот когда несколько процессов могут менять одну переменную — другое дело :)
Когда речь идет о изменении переменной извне процесса, то тогда оно будет неявным для компилятора.
Познавательная статья, спасибо. Думаю, в скором времени она мне пригодиться на практике.
В код не вдавался, скорее в порядок действий, но успел заметить использование функции bzero.
Из мана:
4.3BSD. This function is deprecated (marked as LEGACY in
POSIX.1-2001): use memset(3) in new programs.
Эта функция — одна из рядовых проверок в одном крупном проекте.
Так как пункт про комменты самый первый и ориентирован больше для новичков, то я просто взял эту функцию (в которой изначально комментариев не было), и для наглядности придумал пару поясняющих комментариев.
Если бы надо было проверить что-то еще — да, мы бы написали отдельную функцию.
И она бы вызывалась вместе со всеми проверками. CheckModemConnection() — одна из сотен функций, которые вызываются при обработке пришедшей конфигурации. То есть все — и сеть, и voip, и iptv имеет подобные проверки.
Нужно это, чтобы группировать параметры, и, когда надо добавить новый, знать, где находится проверка группы связанных параметров.
Конфигурация приходит в виде дерева, по конкретным нодам в цикле не пройтись. Разве что, можно создать массив/перечисление с указателями на параметры, и идти по нему… Но это не слишком целесообразно, ибо будет гораздо сложнее найти источник и сразу не скажешь (не смотря на массив), какие параметры подвергаются проверке.
Ну, я только начал знакомство с Go, у меня еще не было проектов на нем, где требовалась бы не последняя версия библиотеки:)
Ну, надеюсь, что все еще впереди.
Rust недавно расхваливал один хороший знакомый, так что рано или поздно я к нему приду, думаю.
А Cargo — уже как получится. Пока вообще не представляю, что это за язык:)
Возможно, я выбрал не очень удачный пример в статье. Да, группировка — очень хорошая практика. И она прекрасно дополняет метод с include'ом.
Я уже писал — ко всему надо подходить с умом. Заголовки общего пользования, библиотечные заголовки, которые должны быть доступны во всем проекте. include — для них самое подходящее место.
Возьмем тот же busybox. В исходниках все группируется именно так, как вы сказали. Каждая утилита в отдельной папке. И .c, и локальные заголовки. Но тем не менее, директория include там тоже есть, и все библиотечные хэдеры живут там:)
Самый популярный файл во всем busybox — обитающий там заголовочник с интригующим названием «Libbb.h»
По поводу полного пути — тут вы не совсем правы. Когда мы указываем директорию include, то поиск заголовочников при линковке будет происходить в ней. Так что можно обойтись указанием имени файла в кавычках :)
Скажу снова: по поводу оформления кода — это не «абсолютные истины», а рекомендации. Практика, которая встречается чаще всего. Кодстайл всегда зависит от конкретного проекта.
По поводу заголовочников стоит написать отдельную статью. В идеале, все заголовочники должны быть оформлены так, чтобы из них можно было понять как можно больше интерфейсов взаимодействия внутри программы.
+ надо понимать, что ничего не стоит делать бездумно. В том же busybox заголовочники бывают 2х типов: общего пользования и локальные. Общего пользования лежат в include в корне, а локальные — в папках с утилитами (подпроектами).
Очень правильный комментарий вот тут, группировка — очень хорошая практика. Однако в системе вынос в инклуд я встречаю гораздо чаще.
Volatiole надо использовать, когда переменные могут быть изменены неявно. Например, если у нас многопоточное приложение, в котором потоки имеют общий доступ к каким-либо переменным.
Тогда любое изменение этих переменных, которое будет сделано из другого, будет неявным для компилятора. Отсутствие volatile в этом случае может положить весь механизм IPC в приложении.
Как я писал в комментариях выше, я не говорю, что нужно писать только так. Это — рекомендации, сделанные на основе самых распространенных практик оформления кода в самых разных проектах.
А по поводу адаптации к рефакторингу… Это очень сложная тема.
Когда я только начинал учить Си, меня часто тюкали по голове за то, что я пишу по-своему, игнорируя общепринятые вещи. Тогда же мне довелось участвовать в небольшом проекте, на последней стадии разработки которого одному опытному программисту поручили выполнить рефакторинг моего кода, ибо он не соответствовал кодстайлу проекта. А кодстайл проекта мы взяли такой же, как в ядре Linux.
Однако, каждый волен сам выбирать свой кодстайл, главное чтоб он не противоречил соглашениям, принятым в проекте:)
+ даже зная, кто и каким каммитом добавил функционал, не всегда можно понять, в рамках какой задачи это было сделано. (не все и не везде указывают).
Да и в любом случае, просто вбить заранее указанный номер задачи в трекер будет в разы быстрее, чем сначала искать «кто, где и зачем».
По поводу того, что комментарии не поддерживают — не соглашусь.
Я бы посмотрел на того, кто бы взялся сопровождать тот же bb, не будь он так хорошо задокументирован)
Если комментарии не нужны, то почему так много рекомендаций из самой различной литературы и интернета отмечают умение грамотно писать комментарии одним из правил хорошего тона?
Обмен сообщениями на сокетах тесно связан со структурой sockaddr_in. В один из ее экземпляров можно записывать адрес клиента, который пытается подключиться.
Если этот вариант не проканает, то можно воспользоваться RAW-сокетами — тогда можно будет распарсить сырой пакет полностью и посмотреть заголовки.
После этого — сравнить сертефикаты.
Последние пару месяцев я моими тасками было ковыряться в сорцах udhcpc и udhcpd, расширяя его функционал.
После всего этого то, что представлено тут, воспринимается очень просто :)
Теперь мне стало ясно, как работать с апи, предоставляемым телеграммом.
Я был приятно удивлен тем, что можно оформить это в виде простого сетевого приложения (у меня уже целая библитека функций для приложений на сокетах).
Поэтому, кмк, профит данной в статьи именно в алгоритме действий.
У тех, кто в первый раз с этим столкнулся перед глазами будет рабочий пример:)
Да, я не прав. Многопоточное приложение тут не при чем, компилятор в состоянии отслеживать изменения переменных в потоках.
А вот когда несколько процессов могут менять одну переменную — другое дело :)
Когда речь идет о изменении переменной извне процесса, то тогда оно будет неявным для компилятора.
В код не вдавался, скорее в порядок действий, но успел заметить использование функции bzero.
Из мана:
Мемсет — наше спасение :)
Так как пункт про комменты самый первый и ориентирован больше для новичков, то я просто взял эту функцию (в которой изначально комментариев не было), и для наглядности придумал пару поясняющих комментариев.
Пометил себе, как появится заряд — с меня плюс в карму :)
Понял ошибку, исправился :)
Спасибо за просвещение :)
Да, вы абсолютно правы, я не правильно понял замысел и интерфейсы bb.
Извиняюсь.
Сейчас отредактирую статью.
И она бы вызывалась вместе со всеми проверками. CheckModemConnection() — одна из сотен функций, которые вызываются при обработке пришедшей конфигурации. То есть все — и сеть, и voip, и iptv имеет подобные проверки.
Нужно это, чтобы группировать параметры, и, когда надо добавить новый, знать, где находится проверка группы связанных параметров.
Конфигурация приходит в виде дерева, по конкретным нодам в цикле не пройтись. Разве что, можно создать массив/перечисление с указателями на параметры, и идти по нему… Но это не слишком целесообразно, ибо будет гораздо сложнее найти источник и сразу не скажешь (не смотря на массив), какие параметры подвергаются проверке.
Ну, надеюсь, что все еще впереди.
Rust недавно расхваливал один хороший знакомый, так что рано или поздно я к нему приду, думаю.
А Cargo — уже как получится. Пока вообще не представляю, что это за язык:)
Отчего-то все называют этот символ именно так :)
Изначально хотел написать «нижний дефис», но меня раскритиковали.
Я уже писал — ко всему надо подходить с умом. Заголовки общего пользования, библиотечные заголовки, которые должны быть доступны во всем проекте. include — для них самое подходящее место.
Возьмем тот же busybox. В исходниках все группируется именно так, как вы сказали. Каждая утилита в отдельной папке. И .c, и локальные заголовки. Но тем не менее, директория include там тоже есть, и все библиотечные хэдеры живут там:)
Самый популярный файл во всем busybox — обитающий там заголовочник с интригующим названием «Libbb.h»
По поводу полного пути — тут вы не совсем правы. Когда мы указываем директорию include, то поиск заголовочников при линковке будет происходить в ней. Так что можно обойтись указанием имени файла в кавычках :)
По поводу заголовочников стоит написать отдельную статью. В идеале, все заголовочники должны быть оформлены так, чтобы из них можно было понять как можно больше интерфейсов взаимодействия внутри программы.
+ надо понимать, что ничего не стоит делать бездумно. В том же busybox заголовочники бывают 2х типов: общего пользования и локальные. Общего пользования лежат в include в корне, а локальные — в папках с утилитами (подпроектами).
Очень правильный комментарий вот тут, группировка — очень хорошая практика. Однако в системе вынос в инклуд я встречаю гораздо чаще.
Volatiole надо использовать, когда переменные могут быть изменены неявно. Например, если у нас многопоточное приложение, в котором потоки имеют общий доступ к каким-либо переменным.
Тогда любое изменение этих переменных, которое будет сделано из другого, будет неявным для компилятора. Отсутствие volatile в этом случае может положить весь механизм IPC в приложении.
А по поводу адаптации к рефакторингу… Это очень сложная тема.
Когда я только начинал учить Си, меня часто тюкали по голове за то, что я пишу по-своему, игнорируя общепринятые вещи. Тогда же мне довелось участвовать в небольшом проекте, на последней стадии разработки которого одному опытному программисту поручили выполнить рефакторинг моего кода, ибо он не соответствовал кодстайлу проекта. А кодстайл проекта мы взяли такой же, как в ядре Linux.
Однако, каждый волен сам выбирать свой кодстайл, главное чтоб он не противоречил соглашениям, принятым в проекте:)