Обновить
77
0

Пользователь

Отправить сообщение
Пытаемся. Наиболее инициативные товарищи образовали т.н. «Совет Эльфов», который принимал все судьбоносные решения подобного рода. Но всегда есть несколько человек, с которыми ничего не поделать. Или встают в позу, или отмахиваются, или просто не видят проблемы. Вот тут бы, на мой взгляд, как раз и стоило бы слегка надавить «административным ресурсом», которым совет не обладает :)
Я не руководитель, опыт у меня и правда небольшой (да еще в одной компании), я просто вижу проблемы вокруг себя. У нас даже просто сидящие в разных концах комнаты люди умудрялись развивать маленькие фабрики велосипедов, несовместимые друг с другом. Просто потому, что они не общались. Каждый сидит в своем углу и делает свое маленькое дело. Что происходит, когда люди сидят в разных комнатах — я вообще молчу.

Отмечу, что у нас своя специфика, очень много небольших проектов, поэтому разработчикам существенно проще не контактировать друг с другом. Но тем не менее.
Если вы решаете за сотрудников как им работать — вы не команда. Вы спускаете сверху git flow, список статусов задач, рабочие часы с 9:00 до 18:00?

Мой небольшой опыт показывает, что если кто-нибудь (необязательно РМ или начальство, просто кто-то, кому не все равно) не придумает, как организовывать работу (банально, конвенции по именованию файлов/директорий, конвенции по кодированию, rebase или merge и т.д.), то все будут делать это как попало. Если всех не приучить юзать git, то у кого-то вообще никакого версирования не будет, кто-то будет архивчики руками делать ежедневно, кто-то svn себе поставит. И код будет расползаться просто файлами по скайпу.

Возможно, если у вас уже есть настоящая команда, в которой все сознательные и рациональные люди, то они видят эту проблему и решают ее сообща, но в реальности таки придется некоторые вещи педалировать сверху, иначе будет просто помойка.
Хотелось бы задать завуалированный вопрос не по статье. Но сперва предыстория:
Около 8 часов мы с коллегой искали баг, который проявлялся в весьма запутанной ситуации. Когда мы его наконец нашли и тщательно побились головой об стол, проклиная свою глупость. И я, разумеется, поднимаю палец в верх и говорю своему коллеге: «А знаешь, как мы могли бы найти этот баг легко? (драматическая пауза) PVS-Studio!»

Да, я очень давно пытаюсь убедить своих коллег в необходимости использования PVS-Studio.

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

В чем же заключался баг?

bool isDone = checkSomeCondition( first );
isDone = isDone && checkSomeCondition( second);


checkSomeCondition — функция с побочными эффектами, которая, как вы уже понимаете, не вызывалась второй раз, если первая проверка возвращала false. Этот код писал я сам (и мне стыдно) и в тот момент я просто напрочь забыл об этом свойстве оператора &&. И, формально, это в общем-то и не баг даже, подобный код можно писать намеренно.

Тем не менее, хотелось бы узнать, рассматривался ли подобный код в кандидаты на предупреждение? Можно ли как-нибудь это предупреждение получить? Допустим, если у функции нет атрибута pure?
А как же моноклональные антитела? Мне казалось, что они специально «нацелены» на раковые клетки.
Комментарий для модуля был весьма абстрактный — «Тут описан такой-то класс, он делает вот это». Какого-то единого метакомментария для всего проекта я не обнаружил. Возможно, конечно, я плохо искал…

Судя по git blame комментарии-шапки добавлялись для какого-то генератора биндингов, видимо, некомментированные функции этому генератору были не нужны.
А как документация для glib поможет мне понять вот эту функцию из библиотеки, которая от glib зависит?
const char *
arv_device_get_string_feature_value (ArvDevice *device, const char *feature)


Она возвращает указатель на строку. Эту строку нужно освобождать? Или не нужно? Комментариев к функции или внутри функции нет вообще. Строка прямо в ней не формируется, она берется из другой функции.

В итоге из-за отсутствия комментария (банально шапки к функции), приходится не просто читать код этой конкретной функции, а прослеживать весь путь, который эта несчастная строка проходит, прежде чем до моего вызова доберется.
Так это и были умные указатели. Только на С. Поэтому ref/unref нужно вызывать руками.
Самая большая моя боль была при первом столкновении с библиотекой, завязанной на glib. Куча функций вообще без единого коммента. Ладно, внутри функций, бог с ним. Но хотя бы о самой функции — что за аргументы, что она возвращает? Нет, зачем, и так же все понятно.

Т.к. многие функции возвращали указатели, постоянно приходилось угадывать, нужно ли потом память по этим указателям освобождать самостоятельно? Или нужно вызывать g_object_unref? Или можно вообще ничего не делать?

Ох и намаялся я, пока все утечки памяти выискивал.
Твоё мнение никому не интересно, можешь сколько угодно распинаться о том как по твоему надо делать, о розовых пони и прочих галлюцинациях.
Я же тебе предложил: иди и сделай, покажи как надо — тогда будет о чём подумать, пока ты очередной теоретег.

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

Я не криптограф и не считаю себя достаточно квалифицированным специалистом, чтобы писать криптографические библиотеки. Однако это не мешает мне чувствовать code smell.

Реальный код это всегда компромисс между: скоростью работы, потребляемыми ресурсами, временем разработки, безопасностью, читаемостью, соблюдением кодстайла, писаниной тестов и документации и тд.

Это утверждение верно. Но в зависимости от области применения этого кода компромисс достигается в разных точках. Сайтик в интернете для 10 друзей можно делать как угодно, но от кода в медицинской или автомобильной технике зависят человеческие жизни! И там надежность играет (или, по крайней мере, должна играть) несколько большую роль, чем количество табуляций или скорость разработки. От криптографии зависят приватность и очень чувствительные данные людей, а иногда и жизнь/свобода.

А вообще, толстовато, уважаемый, толстовато.
Если ты такой идеалист оторванный от реальности, иди разгребай авгиевы конюшни в том же OpenSSH, потом будешь рассказывать про аккуратность, гото, мисра и прочие мастхэв идеалиста.

А, ну правильно, в openssh конюшни и дальше будем такие же конюшни разводить, прально.
Конечно, табуляция ведь гораздо важнее чем чистота кода!
И супер-пупер защищенная от квантовых компьютеров криптография будет за границы массивов выходить. Ну ок, на здоровье.
А что надо на крестах или ГОмосятине какой писать?
goto тоже нормальная практика для err_out/cleanup потому что 100500 проверок и только одно место для очистки всего сразу.

Я не буду говорить про Rust, но можно и на крестах, вообще-то. По крайней мере, типизация построже будет, а публичное API все равно extern «C».

На мой взгляд, goto — это не нормальная практика, это признак слабости и крохоборства :) Всегда можно написать без goto. И это не микроконтроллер с килобайтом памяти, чтобы там так байты и такты экономить.
На мой взгляд, опять-таки, криптографию нужно писать очень, очень, очень аккуратно, вплоть до MISRA C. А MISRA учит нас, что
Rule 14.4 (required): The goto statement shall not be used

По своему опыту могу сказать, что если в коде есть goto, то дальше ожидать можно чего угодно — игнорирования strict aliasing, касты через union, сдвиги отрицательных чисел влево и черт знает что еще.
Компания Microsoft тоже не осталась в стороне и в 2016 году выпустила библиотеку SIDH(Supersingular Isogeny Key Exchange) с открытым исходным кодом. Одним из преимуществ данной библиотеки является возможность использования эллиптических кривых в форме Монтгомери, которые защищают от атак по времени.

Вау, подумал я. Круто!

SIDH реализована на языке C

Oh wait…

if (CurveIsogeny == NULL) {
Status = CRYPTO_ERROR_NO_MEMORY;
goto cleanup;
}


Ну блин, опять пошло-поехало…
А есть какие-нибудь исследования на тему того, как же все-таки читают саванты? Которые одним взглядом всю страницу окидывают?
Как у них глаза успевают вообще весь текст пробежать?
Сделать хороший текстовый конфиг — тоже не так-то просто, на самом деле.
Помнится, пришлось мне пользоваться одной САПР, которая настройки в файле хранила…

  • Настроек было пару тысяч, изначально в файле присутствовала пара сотен.
  • Настройки назывались типа «allow_harn_mfg_assy_retrieval » или «style_grid_spacing». Разумеется, среди них были ну очень похожие по названию, но совсем разные по действию.
  • То, что в файле уже было, не было отсортировано по алфавиту или еще как-то сгруппировано, просто все подряд навалено.
  • Некоторые опции конфликтовали друг с другом.
  • Разумеется, существовали огромные талмуды, где перечислялись все возможные опции, только надо было тщательно смотреть на соответствие версии талмуда и версии САПРа, потому что старые опции переставали работать, зато появлялись новые.


Причем я так и вижу, что давным-давно этих опций было штук 10 и кто-то подумал — «Да лааадно, и так вроде все понятно».

Так и не удалось мне рамку по ГОСТу сделать.
Прошу прощения, если не по адресу, но очень меня такой вопрос интересует — а чем безопасно мыть, скажем, ванну, восстановленную акрилом? А то повсюду довольно противоречивая информация, то можно кислотными средствами, то ни в коем случае.
Однозначно нельзя абразивами, в это я верю, а вот насчет кислот-щелочей очень интересно (ибо просто мылом или фейри отмывается она не очень).
По поводу полного пути — тут вы не совсем правы

Я просто подумал, что вы предлагаете в папке include дублировать всю структуру каталогов для исходников, а не держать там только глобальные заголовочники. Если в папку include не совать вообще все заголовочные файлы, а только глобальные, то никаких возражений у меня нет.
Храните заголовочники в директории include.

А не могли бы вы объяснить, какой смысл делать отдельную директорию include? Я в этом вижу только минусы:
  • нужно прописывать еще один путь в настройках проекта
  • дерево проекта увеличивается вдвое, ведь внутри папки include приходится повторять всю структуру папок с файлами .c
  • в файле xx.c нельзя просто написать include «xx.h», приходится писать полный путь до него — #include «yyy/zzz/xx.h»
  • чтобы скопировать какой-то «модуль», вам приходится копировать два файла из разных мест

Гораздо удобнее, на мой взгляд, группировать файлы в папке по принципу «модулей». Допустим, модуль Common — это отдельная папка, в ней common.c и common.h. Этот модуль приобретает «позиционную независимость», т.е. когда вы его копируете в другой проект, вам не надо переписывать инклуд в файле common.c. Ну и все минусы, описанные выше, пропадают.
Конечно, какой-то разумный предел сверху нужен, не надо позволять делать пароли в килобайт длиной, но 20 символов — это, все-таки, перебор. Даже отдельные слова бывают длиннее.

Вот, скажем, 255 символов — вполне разумный предел.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Зарегистрирован
Активность