Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали:
S>Ну вот сходу типичное для чисто Сишного кода: как понять, где в коде этой функции можно сразу делать retun r;, а где нужно r = ...; goto out, а где r = ...; goto cancel_injection;? Посредством каких-то тайных знаний, штудирования документации, штудирования комментариев или внимательного разбирательства с кодом этой функции?
Это освобождение ресурсов, достаточно очевидное как всегда в таких случаях. В строке 8321 в guest инжектится прерывание, сводится к
inject_pending_event:
else if (vcpu->arch.interrupt.injected)
kvm_x86_ops->set_irq(vcpu);
Если после этого до переключения исполнения в guest произошла ошибка или изменено решение о переходе в guest, естественно нужно это прерывание сбросить, поэтому goto cancel_injection. Соответственно до строки 8321 с инжектом прерывания, правилен goto out. По-моему это вполне очевидно.
А ты бы использовал исключения или RAII? Наверное можно. С освобождением ресурсов кстати реально бывает много багов в линуксе, но обычно менее очевидных, чем goto не на ту метку выхода. Я например, очень редко забываю что-то освободить в простых случаях, скорее мешают логические ошибки при выходе из середины функции.
Кроме того, с goto код очевиден. А вот в С++ обычно код менее явный и нужно вникать где же ресурс на самом деле освободится. Впрочем можно было это и с использованием С++ это написать, были бы и преимущества такого подхода. Но если в ядро еще добавить мув-семантику и сложные шаблоны, то в нем точно очень мало кто сможет разобраться, т.к. там и без них сложностей хватает.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>Это освобождение ресурсов,
Это очевидно.
lpd>достаточно очевидное как всегда в таких случаях.
Аж два раза. Вы даже суть вопроса не поняли, а уже объяснять побежали.
Вопрос был в том, как не вычитывая досконально весь код этой портянки понять, что вот здесь при добавлении нового фрагмента еще можно делать goto out, а вот здесь уже только goto cancel_injection.
Очевидно, что никак.
lpd>А ты бы использовал исключения или RAII?
Не пытайтесь думать за других.
Исключения здесь не нужны. А вот RAII и какой-то вариант scope guard-а помог бы.
lpd>Кроме того, с goto код очевиден.
Здравствуйте, so5team, Вы писали:
S>Вопрос был в том, как не вычитывая досконально весь код этой портянки понять, что вот здесь при добавлении нового фрагмента еще можно делать goto out, а вот здесь уже только goto cancel_injection.
S>Очевидно, что никак.
Модифицировать функцию, не читая ее код, и не понимая что она делает — это действительно высший пилотаж, мне такое не под силу.
Ну и в конкретно этом примере RAII помог бы слабо, т.к. это не освобождение ресурса, а вызов специальных функций, и в лоб по С++ному ничего тут не сделать.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, smeeld, Вы писали:
S>Здравствуйте, Mystic Artifact, Вы писали:
MA>> Это говорит о многом.
S>Это говорит прежде всего о том, что вы не учитываете политический момент. S> А именно он и определяет то, каким компилятором должен собираться линукс.
Бред какой-то. Столлман никак не может повлиять на разработку ядра,
даже на текущий процесс разработки gcc он может очень слабо повлиять.
На разработку ядра могут повлиять крупные компании, которые собственно
и оплачивают весь банкет. Но возьмем например redhat,
если посмотреть логи git llvm/clang, там куча коммитов от @redhat.com.
Здравствуйте, lpd, Вы писали:
lpd>Модифицировать функцию, не читая ее код, и не понимая что она делает — это действительно высший пилотаж, мне такое не под силу.
Между тем такое происходит сплошь и рядом: есть функция, которая перед выполнением некого главного действия X выполняет серию проверок и подготовительных действий P1, P2, ..., Pn. Спустя какое-то время выясняется, что между Pi и P(i+1) нужно вставить еще и P(i'). Которое может завершится неудачно и в случае ошибки нужно сделать преждевременный возврат.
Когда пишется нормальный код, то можно просто сделать return.
Когда все, что есть в вашем распоряжении -- это чистая ламповая Сишечка с goto err, то да, пока не проштудируешь простыню на 10 экранов, добавить P(i') не получится.
И, что характерно, штудируют не все, и не всегда тщательно.
lpd>Ну и в конкретно этом примере RAII помог бы слабо, т.к. это не освобождение ресурса, а вызов специальных функций, и в лоб по С++ному ничего тут не сделать.
Это говорит лишь о том, что вы слабо себе представляете, что в современном C++ можно делать с помощью RAII (да и в старом, только там несколько многословнее все).
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали:
S>И, что характерно, штудируют не все, и не всегда тщательно.
Тут штудировать нечего, освобождение ресурсов и другие подобные операции вполне очевидны.
S>Это говорит лишь о том, что вы слабо себе представляете, что в современном C++ можно делать с помощью RAII (да и в старом, только там несколько многословнее все).
Создать объект-обертку над функцией? Спасибо, у меня других проблем хватает, чем городить такие конструкции на ровном месте, и усложнять код.
Бог с ним с RAII, если он так нравится, это вопрос стиля. Я больше про мув-семантику, шаблоны и умные указатели писал, впрочем по-моему не раз уж спорил здесь, в том числе с вашими.
Я привел пример кода который я считаю приятно читать и писать. О вкусах спорить не буду, но надеюсь программисты в массе все же поймут что современный С++ это только для фанатиков фич языка, пытающихся все проблемы решить новым синтаксисом, а не для реального кода, в котором и без того сложностей хватает.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
S>>Не, так не пойдет. Дайте, пожалуйста, ссылку на конкретный фрагмент кода.
lpd>Ну вот тебе большая функция-кошмар плюсовика: kvm
Почему, кстати, все в if'ах, там else if'ы имхо нужны, я так понимаю, там всё же не флаги проверяются, а типа enum'ы
Здравствуйте, lpd, Вы писали:
S>>И, что характерно, штудируют не все, и не всегда тщательно.
lpd>Тут штудировать нечего, освобождение ресурсов и другие подобные операции вполне очевидны.
Они так очевидны, что вы даже не поняли, о чем я вас спрашивал.
Полагаю, сишники считают такие вещи очевидными потому, что подолгу сидят над одной и той же кодовой базой. А по другому и не получается. В смысле быстро с сишным кодом не разберешься. Потому успевают вызубрить код, по котором приходится ползать со скоростью мухи.
S>>Это говорит лишь о том, что вы слабо себе представляете, что в современном C++ можно делать с помощью RAII (да и в старом, только там несколько многословнее все).
lpd>Создать объект-обертку над функцией? Спасибо, у меня других проблем хватает, чем городить такие конструкции на ровном месте, и усложнять код.
Вы бы взяли на себя труд и ознакомились бы с предметом разговора. А то выступаете в духе "Пастернака не читал, но осуждаю".
lpd>Я больше про мув-семантику, шаблоны и умные указатели писал, впрочем по-моему не раз уж спорил здесь, в том числе с вашими.
И где в приведенных вами примерах можно увидеть адекватную замену всему вышеперечисленному, но в рамках чистого Си?
Уж не думаете ли вы, что если на C++ придется написать подобный линейный код, как во фрагменте из kvm, то там на ровном месте наплодят еще один boost.xpressive?
lpd>Я привел пример кода который я считаю приятно читать и писать.
Не видно ни того, ни другого. Особенно письмо требует чрезвычайной внимательности и осторожности + глубокого понимания всех деталей и исторических наслоений.
Пример этого уже был приведен выше.
lpd>но надеюсь программисты в массе все же поймут что современный С++ это только для фанатиков фич языка, пытающихся все проблемы решить новым синтаксисом, а не для реального кода, в котором и без того сложностей хватает.
Тут бы очень не помешал пример такого C++ного кода-страшилки с альтернативной реализацией на чистом Си. Чтобы сразу стало понятно, что те же самые задачи можно решать проще, компактнее, дешевле и с меньшим количеством ошибок.
Здравствуйте, lpd, Вы писали:
lpd>Бог с ним с RAII, если он так нравится, это вопрос стиля. Я больше про мув-семантику, шаблоны и умные указатели писал, впрочем по-моему не раз уж спорил здесь, в том числе с вашими.
не буду спорить про шаблоны, с ними и правда можно написать так, что потом сам черт ногу сломит (а можно и наоборот), но что не так с мув-семантикой и умными указателями?
мув-семантика, помимо возможности оптимизации некоторых вещей позволяет выразить в коде явным образом владение ресурсом, следовательно она упрощает код
с умными указателями та же история, если не абьюзить shared_ptr, то в коде становится явно видно что у одного объекта единственный владелец, а у другого нет
Здравствуйте, chaotic-kotik, Вы писали:
CK>мув-семантика, помимо возможности оптимизации некоторых вещей позволяет выразить в коде явным образом владение ресурсом, следовательно она упрощает код
Оптимизацию я не считаю за плюс, т.к. в тех редких случаях когда копирование памяти занимает значительное время в критическом участке, проще скопировать указатель вручную(что мув семантика и делает по сути).
В плане использования для владения ресурсом, то если вы получите преимущества, то ок. Для чего только, все ради хэндлов и файлов? Лично мне такое не нужно было никогда в коде, особенно чтобы это оправдывало новый тип rvalue-reference и все сложности сопутствующего синтаксиса.
И особенно когда некоторые начинают делать мув всех переменных в коде каких можно, это точно абсурд.
CK>с умными указателями та же история, если не абьюзить shared_ptr, то в коде становится явно видно что у одного объекта единственный владелец, а у другого нет
Умные указатели полезная вещь, я и сам их как-то реализовывал. Но это в некоторых случаях, когда владение объектами без него участь сложно; и не нужно делать все указатели умными, как рекомендуют фанатики С++. Вообще, умные указатели не снимают головной боли с круговыми ссылками, поэтому если уж делать нормально, то сборка мусора удобнее, отключаемая конечно.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>Но это лучше мув-семантики на каждом шагу лишь бы ее использовать.
Всегда раньше лоллировал с таких аргументов. Если речь идет о С++ то конечно пренепременно должен быть МАКСИМАЛЬНЫЙ abuse и overuse ВСЕХ возможностей языка ( даже не обсуждается ). Но если речь о C, то конечно по умолчанию всегда идеальный, кристальной чистый код, не иначе как самим господом богом написаный. И конечно ж не может и речи идти о лишнем или нецелесообраном использованием goto, арифметики указателей, void*, привидиния всего ко всему, ООП головного мозга и макросов. Все и всегда только по делу.
Здравствуйте, lpd, Вы писали:
lpd>Здравствуйте, chaotic-kotik, Вы писали:
CK>>мув-семантика, помимо возможности оптимизации некоторых вещей позволяет выразить в коде явным образом владение ресурсом, следовательно она упрощает код
lpd>Оптимизацию я не считаю за плюс, т.к. в тех редких случаях когда копирование памяти занимает значительное время в критическом участке, проще скопировать указатель вручную(что мув семантика и делает по сути).
скопировать указатель намного проще чем скопировать и проследить, чтобы новый владелец его удалил
помимо этого, не все живет в куче, а добавлять лишний indirection не всегда вариант
еще move позволяет упростить некоторые вещи, например сложную синхронизацию можно сделать с использованием unique_lock + move
lpd>В плане использования для владения ресурсом, то если вы получите преимущества, то ок. Для чего только, все ради хэндлов и файлов? Лично мне такое не нужно было никогда в коде, особенно чтобы это оправдывало новый тип rvalue-reference и все сложности сопутствующего синтаксиса.
но если он уже есть, то почему бы и нет? с unique_ptr работа со всякими хэндлами и файлами реализуется очень тривиально, почему бы не пользоваться? накладных расходов 0, ничего не течет, все гарантированно удаляется и освобождается
lpd>И особенно когда некоторые начинают делать мув всех переменных в коде каких можно, это точно абсурд.
явный move редко когда бывает нужен, если по хорошему
CK>>с умными указателями та же история, если не абьюзить shared_ptr, то в коде становится явно видно что у одного объекта единственный владелец, а у другого нет
lpd>Умные указатели полезная вещь, я и сам их как-то реализовывал. Но это в некоторых случаях, когда владение объектами без него участь сложно; и не нужно делать все указатели умными, как рекомендуют фанатики С++. Вообще, умные указатели не снимают головной боли с круговыми ссылками, поэтому если уж делать нормально, то сборка мусора удобнее, отключаемая конечно.
сборка мусора може и удобнее но тормознее, цикличесские ссылки дебажатся довольно тривиально, unique_ptr циклических ссылок не создает в принципе, без того же unique_ptr крайне геморно освобождать память при наличии исключений, тривиальный пример:
x = new X();
y = new Y(); //< throws exception
против
x = std::make_unique<X>();
y = std::make_unique<Y>();
Здравствуйте, chaotic-kotik, Вы писали:
CK>Здравствуйте, lpd, Вы писали:
CK>но если он уже есть, то почему бы и нет? с unique_ptr работа со всякими хэндлами и файлами реализуется очень тривиально, почему бы не пользоваться? накладных расходов 0, ничего не течет, все гарантированно удаляется и освобождается CK>еще move позволяет упростить некоторые вещи, например сложную синхронизацию можно сделать с использованием unique_lock + move
Во-первых, мув-семантика — это не тривиально. Это новый тип с новыми правилами работы с ним, без опыта с которыми будут сложности.
Во-вторых, RAII это не серебрянная пуля. Полно случаев когда он не описывает сложное владение объектом.
CK>>>с умными указателями та же история, если не абьюзить shared_ptr, то в коде становится явно видно что у одного объекта единственный владелец, а у другого нет
Может это и ясно, но синтаксис у умных указателей очень громоздкий. И тут начнутся всякие auto, с которыми уже вообще ничего в коде не видно.
CK>сборка мусора може и удобнее но тормознее, цикличесские ссылки дебажатся довольно тривиально
Не уверен что так тривиально они дебажатся всегда.
CK>, unique_ptr циклических ссылок не создает в принципе, без того же unique_ptr крайне геморно освобождать память при наличии исключений, тривиальный пример:
Я бы предпочел вручную освобождение прописать, хотя если нравится RAII то могу понять.
CK> сборка мусора може и удобнее но тормознее
Вроде как никто не мешает тормозящие массовые объекты и самому при сборке мусора удалять(тут я не специалист). Если сборка мусора тормозит, ее можно отключить и перейти на ручную работу с памятью или умные указатели.
Вообщем, если очень нравится RAII, то я могу понять твои аргументы.
Но лично я подписывался под старым С++03. И появись С++17 одновременно с ним, под другим названием(ComplexC, например), я бы писал на С++03, как наверняка и многие другие.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
что будет, если мне потребуется вместо skb_rbtree_walk_from(skb) написать skb_rbtree_walk_from(skb++)?
Полагаю, разбираться в чужих макросах сильно проще, чем в чужих шаблонах.
Ну и отдельный вопрос: а зачем этот макрос вообще потребовался, ведь на Си так легко и просто понятный код писать, а тут на одном for-е почему-то экономят.
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали:
S>что будет, если мне потребуется вместо skb_rbtree_walk_from(skb) написать skb_rbtree_walk_from(skb+1)?
Ты наверное понимаешь, что skb — указатель, и (skb+1) в данном случае смысла не имеет.
Будет просто:
Так что непонятно в чем твоя претензия в данном случае.
S>Полагаю, разбираться в чужих макросах сильно проще, чем в чужих шаблонах.
Макросы — это всего лишь препроцессор, поэтому они проще шаблонов, как ни крути.
S>Ну и отдельный вопрос: а зачем этот макрос вообще потребовался, ведь на Си так легко и просто понятный код писать, а тут на одном for-е почему-то экономят.
Для итерации в ядре макросов много, включая обычные list, rcu, rb_tree и прочие частные for_each_process() и for_each_device(). Вообще итерация по спискам в ядре довольно специфичная через получение адреса структуры по ее полю list_head, но достаточно один раз разобраться с list, и дальше просто пользоваться остальными макросами. В любом случае если нужно разобраться в участке кода, то у макросов названия достаточно понятные, и они не затрудняют эту задачу.
Контейнеров в ядре в такой форме как в С++ нет, как и классов, — это наверное плохо, должен согласиться. Классический С++ был бы удобнее, но можно писать понятный код и с макросами. Я же не говорю, что С лучше С++98. Хотя для С легче понять где какой метод вызывается без виртуальных функций(аргумент Линуса). Также в С полегче предсказать какой бинарный код получится и разбираться в ассемблерных дампах, что в ядре является плюсом.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
lpd>Вообщем, если очень нравится RAII, то я могу понять твои аргументы. lpd>Но лично я подписывался под старым С++03. И появись С++17 одновременно с ним, под другим названием(ComplexC, например), я бы писал на С++03, как наверняка и многие другие.
Так пиши на С++03, кто тебе мешает?
Я так и делаю, за исключением некоторых новых мелочей типа лямбд и тп.
S>>Полагаю, разбираться в чужих макросах сильно проще, чем в чужих шаблонах.
lpd>Макросы — это всего лишь препроцессор, поэтому они проще шаблонов, как ни крути.
Здравствуйте, Шахтер, Вы писали:
Ш>Комитет по стандартизации пора расстрелять. Такое ощущение, что эти дебилы никогда не писали софт сложнее hello world.
Ш>
Здравствуйте, lpd, Вы писали:
lpd>Ты наверное понимаешь, что skb — указатель, и (skb+1) в данном случае смысла не имеет. lpd>Будет просто skb_rbtree_walk_from(skb_rb_next(skb)). Так что непонятно в чем твоя претензия в данном случае.
А вы, наверное, не понимаете, что вместо (skb+1) может быть что угодно. Скажем (skb++). И тогда макрос развернется во что-то вроде
for (; skb++ != NULL; \
skb++ = skb_rb_next(skb++))
lpd>Макросы — это всего лишь препроцессор, поэтому они проще шаблонов, как ни крути.
Сами по себе, возможно. А вот то, что на макросах пытаются строить...
lpd>Также в С полегче предсказать какой бинарный код получится и разбираться в ассемблерных дампах, что в ядре является плюсом.
Т.е. высказанные вами предпочтения должны приниматься во внимание только при разработке ядра Linux-а, правильно?
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали: S>А вы, наверное, не понимаете, что вместо (skb+1) может быть что угодно. Скажем (skb++). И тогда макрос развернется во что-то вроде
Никто в здравом уме не напишет (skb++), поскольку это не указатель на члены массива. Аргумент понятен, но надо понимать что пишешь, без этого все равно никак.
S>Т.е. высказанные вами предпочтения должны приниматься во внимание только при разработке ядра Linux-а, правильно?
Относительно макросов и С, да, больше про ядро ОС.
Насчет фич вроде мув-семантики и умных указателей — к С++ вообще. О вкусах не спорят, но мне не нравится что С++17 является законодателем мод(в том чисел в вакансиях), я считаю исключительно за счет эксплуатации успеха классического С++, а не из-за направления развития.
Если вам так нравится С++17 — ради бога, страдайте и мучайтесь, я же поищу проекты на обычном С++ — у меня и так проблем хватает чтобы еще ломать голову нужен мув или нет, и искать где именно неявно разлочится lock_guard.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)