| BG Development · За реклама · За контакти |
Помощ Търсене Потребители Календар Правила |
| Здравей! ( Включване | Регистриране ) |
| Страници: (8) 1 [2] 3 4 ... последна » ( Първото ново мнение ) | ![]() ![]() ![]() |
| dvader |
Публикувано на: 25-04-2025, 13:09
|
||
![]() Име: Валерий Тодоров Група: VIP Ранг: Почетен член Мнения: 5419 Регистриран на: 12.07.05 |
Правилно... Затова ако не можеш да отвориш файла (нормална ситуация) връщаш хендъл към /dev/nul, ако не можеш да го отвориш при ненормална ситуация fopen вика exit() и не се занимаваме с проверки на грешки. Като върнеш /dev/nul следващият който ще чете данните ще пречете 0 (което също е валиден кейс) и ще върне нагоре по веригата нещо друго дефолтно. Ексепшъна ми трябва за кейса когато правя fopen и получавам null pointer или ако правя fread и получавам invalid handle. И в двата случая съм в такъв стейт, от който няма смисъл да се опитвам да излизам. Въпросът е само дали try/catch ще ме върнат в main или ще се рестарирам и пак ще се озова в мей. Разаликата е, че като излизам с try/catch имам шанс да запазя някакви данни, докато при exit губя всичко. За embedded това не е голяма разлика, щото рама не се нулира, ама пък тогава трябва да следя за повторна грешка след рестарт и при вторият опит да нулирам РАМ-а, щото може да е corrupted и той и тогава вече почваме от нулата. Въпросът беше, че ако викаме exit при критична грешка защо трябва ние самите да го правим а не го прави самата функция, която връща код за грешка. -------------------- I find your lack of faith disturbing
|
||
| dvader |
Публикувано на: 25-04-2025, 13:15
|
||
![]() Име: Валерий Тодоров Група: VIP Ранг: Почетен член Мнения: 5419 Регистриран на: 12.07.05 |
Нещо бъркаш. Моят отговор е "не" и *ползвам* изключения, щото те ме връщат нейде в началото в някакво стабилно състояние без да се налага сам да чистя нещата по целият кол-стек. Ако функцията НЕ МОЖЕ да ми върне валидни данни, това е изключение. "Валидни данни" са такива, с които мога а продължа да работя без за изпадна в seg fault или да генерирам corrupted дата. И ако чак толкова не искаме да ползваме изключения си имаме errno - можем да си го проверим като се върнем най-горе по веригата -------------------- I find your lack of faith disturbing
|
||
| Дон Реба |
Публикувано на: 25-04-2025, 13:30
|
||
|
Име: Група: Потребител Ранг: Почетен член Мнения: 10496 Регистриран на: 11.11.06 |
ако не си забелязал, if(!(f=fopen()))return 0; е по-малко писане от try-catch, отделно че самото наличие на ексепшън механизъм е причината разни функции да крашват ако им подадеш невалиден файл. замислял ли си се, защо вин32 апитата НЕ крашват ако им дадеш невалиден хендъл? например SetWindowText(0,"proba"); няма да крашне, докато fwrite крашва. причината е че вин апито е старо и е писано на паскал, преди да има ексепшъни. това му поведение е по стандарт заложено, апитата почнаха да крашват чак когато се въведоха ексепшъните. т.е. ексепшъните ти "оправят" проблем който самите те създадоха |
||
| SuN |
Публикувано на: 25-04-2025, 14:56
|
||||||||||||
|
Име: Група: Администратор Ранг: Почетен член Мнения: 13461 Регистриран на: 27.01.05 |
Защо в темата спорят хора, които даже не са прочели нещо за този Ръждясал език?
Имаш функция panic, която убива програмата. Линус много се кара на на ентусиастите, които искаха да пишат драйвери на Ръст за тази глупост. Каза им да си пренапишат стандартната библиотека или да спрат.
Имаш интерфейси. В С++ това поведение се емулира с виртуални класове.
Я пробвай в една програма да имаш две библиотеки със синхронен и несинхронен код.
И аз мисля, че поведението на компилатора и езика по подразбиране е по-хубаво в Ръст. Имаше риск и в С++ да станат подобни нещата, затова комитета изрично "отслабва" предложения в новите стандарти за да поддържа UB.
Да им дадем малко време да се посменят кадрите и да ги питаме пак. П.п. И след коментара си виждам, че има нова версия на ГЦЦ. А в промените пише:
-------------------- Само аз не троля.
Всички коментари са плод на художествена измислица и нямат общо с действителни и недействителни лица, събития и факти. |
||||||||||||
| dvader |
Публикувано на: 25-04-2025, 15:53
|
||
![]() Име: Валерий Тодоров Група: VIP Ранг: Почетен член Мнения: 5419 Регистриран на: 12.07.05 |
Точно за това иде реч - НЕ Е по-малко писане, защото ще пишеш if (0 == на *всяка* функция по веригата - fopen, fread и накрая на fclose. И в случай, че ползваме кодове за грешки, всяка от тези проверки ще върне кодът за грешка на по-горното ниво, където ще пише нови if (0 == и ще връщаш кодове на още по-горно ниво. С изключенията нещата не се правят така - try/catch блока се слага на най-горното и хваща *всичките* throw по веригата. Разглеждай try/catch като pubslish/subscribe архитектура а всеки throw - като notify Дали трябва да крашва функцията при неправилни данни зависи от това дали трябва да крашва или не Например, strlen(nullptr) ще крашне, lstrlenA(nullptr) няма - коя от двете се държи правилно? Освен това, винапитата крашват като слънце - лично съм правил BSOD на Windows 2000 с ReadFile(). Само че това по-скоро беше бъг, в ХР вече не минаваше номера. Ако имаш предвид краш на някое АПИ *без* BSOD то това ще опре до въпросът какво наричаме WINAPI. Но дори и в този случай, можеш ли да кажеш пример за такова АПИ? Знам само АПИ-та, които си хвърлят изключения вътрешно (и се виждат само на дебъгер) което не знам дали можем да го наречем краш. Не на последно място fwrite не е WINAPI. Проблемът с изцепшъните е друг - не са част от ABI-то, което значи, че не можеш да ги ползваш между модули написани на различни езици и дори на различни компилатори на един език. Ако обаче си компилираш всичко от и до и получаваш едно ЕХЕ, тогава са много по-удобни. PS. WINAPI от край време има RaiseException -------------------- I find your lack of faith disturbing
|
||
| ici |
Публикувано на: 25-04-2025, 17:23
|
![]() Име: Ивайло Илчев Група: VIP Ранг: Почетен член Мнения: 19077 Регистриран на: 06.06.04 |
Тоя прост трик ти увличава кода с около 40%, а стека четири пъти
-------------------- Facebook is a bit like checking your underwear after a fart.
Most likely there's nothing new and if there is it's probably shit. |
| dvader |
Публикувано на: 25-04-2025, 18:49
|
||
![]() Име: Валерий Тодоров Група: VIP Ранг: Почетен член Мнения: 5419 Регистриран на: 12.07.05 |
А тези цифрички са откъде? За x86 се добавяше по един адрес в един свързан списък в стека - не ми изглежда като 4х стек, нито увеличение на кода с 40%. Пък и от къде ще дойде увеличението на кода - генерира се просто един return (който си генерира виканията на деструкторите). Ако го добавиш този return с макрос ще получиш същият код за викането на деструкторите и ще се различава само, че няма да го има викането на следващият елемент от списъка, което е 2 инструкции. Единствено имаш runtime penalty за добавяне/махане от стек, което е 3 инструкции за добавяне, две инструкции за махане. На х64 го правят дори бе промяна на кода - кода е 1:1 с и без изключения, но пък се добавят яко таблици с адреси, по които после става stack unwind-а. Но си признавам, че нямам идея колко са обемни. При това положение нормалният code flow е без penalty, но за сметка на това извикването на throw става мнооого бавно... но пък се предплага, че throw се вика мнооого рядко. От друга страна - а колко е спестеното време? Процесорът отдолу е един и същ, независимо от езика, така че оптималното решение ще заема един и същи обем от код/време, независимо от езика. -------------------- I find your lack of faith disturbing
|
||
| Bender++ |
Публикувано на: 25-04-2025, 19:58
|
||||||||||
![]() Име: Група: Потребител Ранг: Старо куче Мнения: 608 Регистриран на: 18.04.21 |
Holy Rust не e Golang, и този проблем го няма
Нямаш ли хубава билд система, нямаш нищо. Даже умрялата билдсистема в голанг е по-добре от цмаке
правилата на езика правят невъзможни race conditions в safe rust. Винаги може в unsafe с raw pointers да намажеш нещата
това в ръст му казваме panic_handler и за ембеддед имаш няколко опции - безхраен цикъл, halt на цпу-то, etc.
Нуждите на user-space & kernel space са различни Това мнение е било редактирано от Bender++ на 25-04-2025, 20:01 -------------------- Слава на Цар Путин! Долу украинските фашисти!
|
||||||||||
| dvader |
Публикувано на: 25-04-2025, 21:34
|
||
![]() Име: Валерий Тодоров Група: VIP Ранг: Почетен член Мнения: 5419 Регистриран на: 12.07.05 |
Как става номера? Питам съвсем сериозно, щото подозирам, че просто са вградили статичен анализатор в езика. -------------------- I find your lack of faith disturbing
|
||
| Bender++ |
Публикувано на: 25-04-2025, 23:37
|
||||||||
![]() Име: Група: Потребител Ранг: Старо куче Мнения: 608 Регистриран на: 18.04.21 |
Има няколко механизма, които работят заедно: * Идеята за ownership - всяка променлива може да има само 1 owner, Когато променливата излезе от скоуп, паметта се деалокира. * Ръст прави разлика между read-only & mutable променливи & референции. По подразбиране, всичко е read-only. Може да имаш колкото си искаш RO референции към нещо, стига да нямаш нито една mut референция. Или може да имаш само 1 единствена mut референця, но тотгава - нито една RO. Тоест ако се опиташ да подадеш някаква структура чрез референция (разбирай чрез малко по-специален поинтер), компилатора няма да ти посволи да създадеш 2 референции едновременно които да позволяват промяна на данните - тоест ако можеш да ги променяш само от 1 място, то тогава няма как да имаш data race. * Почти всичко има move семантика, за разлика от легаси езиците, където всичко има copy семантика. Copy семантика имат само типовече които имплементират Copy интерфейса, като има ограничения кой може да го имплементира - само типове които нямат деструктор и тези, чиито всички мембъри имплементират копи.. Тоест като подадеш като параметър някаква структура по стойност, тя се "мести" и е компилационна грешка да имаш указател към невалидна памет (тоест старата променлива), следователно пак имаш само един owner, следователно няма как да имаш data race ако може да пишеш само от едно място. * Има 2 интерфейса - Send & Sync, които се имплементират автоматично от компилатора, но може и ръчно: - Send - инстанциите на типа Т може да се местят между нишките - Sync - референции към типа Т (&T) могат да се местят между нишките (тоест може да имаме споделен достъп) Примери Ownership & Move semantics:
Shared & Exclusive references:
Rc<T> е смарт reference counted поинтер, който не е Send защото ако се ползва от много нишки еновременно, брояча ще се намаже
Sync: Arc<T> е смарт atomic reference counted поинтер, който е Send защото атомик брояча може безопасно да се модифицира от няколко нишки едновременно Мутекса е sync, защото имплементацията му се грижи да не се нарушават правилата на езика. Може от колкото си искаш нишки да кажеш lock(), и той ще се погрижи максимум 1 нишка да държи лока във всеки идин момент от времето и по този начин да имаш 0 или 1 mutable референции.
-------------------- Слава на Цар Путин! Долу украинските фашисти!
|
||||||||
Страници: (8) 1 [2] 3 4 ... последна » |
![]() ![]() ![]() |