BG Development


Страници: (8) 1 [2] 3 4 ... последна »  ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> Къде е Ръждата?!
dvader
Публикувано на: 25-04-2025, 13:09
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



QUOTE (Дон Реба @ 25-04-2025, 10:49)
защото няма такова нещо като "изключение", всички ексепшъни са нормални клонове на изпълнение и не бива да се третират като нещо

Правилно...

Затова ако не можеш да отвориш файла (нормална ситуация) връщаш хендъл към /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
PM
Top
dvader
Публикувано на: 25-04-2025, 13:15
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



QUOTE (DarkOne @ 25-04-2025, 13:09)
Концептуалният въпрос е трябва ли всички грешки да се обработват. Твоят отговор е "не" и затова не проверяваш за грешки и не ползваш изключения.

Нещо бъркаш.
Моят отговор е "не" и *ползвам* изключения, щото те ме връщат нейде в началото в някакво стабилно състояние без да се налага сам да чистя нещата по целият кол-стек.

Ако функцията НЕ МОЖЕ да ми върне валидни данни, това е изключение.
"Валидни данни" са такива, с които мога а продължа да работя без за изпадна в seg fault или да генерирам corrupted дата.

И ако чак толкова не искаме да ползваме изключения си имаме errno - можем да си го проверим като се върнем най-горе по веригата icon_smile.gif


--------------------
I find your lack of faith disturbing
PM
Top
Дон Реба
Публикувано на: 25-04-2025, 13:30
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 10496
Регистриран на: 11.11.06



QUOTE (dvader @ 25-04-2025, 13:09)

Ексепшъна ми трябва за кейса когато правя fopen и получавам null pointer

ако не си забелязал, if(!(f=fopen()))return 0; е по-малко писане от try-catch, отделно че самото наличие на ексепшън механизъм е причината разни функции да крашват ако им подадеш невалиден файл. замислял ли си се, защо вин32 апитата НЕ крашват ако им дадеш невалиден хендъл? например SetWindowText(0,"proba"); няма да крашне, докато fwrite крашва. причината е че вин апито е старо и е писано на паскал, преди да има ексепшъни. това му поведение е по стандарт заложено, апитата почнаха да крашват чак когато се въведоха ексепшъните. т.е. ексепшъните ти "оправят" проблем който самите те създадоха
PM
Top
SuN
Публикувано на: 25-04-2025, 14:56
Quote Post


Group Icon
Име:
Група: Администратор
Ранг: Почетен член

Мнения: 13461
Регистриран на: 27.01.05



Защо в темата спорят хора, които даже не са прочели нещо за този Ръждясал език?

QUOTE
Скапаните exception-и са разкарани... няма да се чудя кат' ненормален отде ще ми хвърли нещо...

Имаш функция panic, която убива програмата. Линус много се кара на на ентусиастите, които искаха да пишат драйвери на Ръст за тази глупост. Каза им да си пренапишат стандартната библиотека или да спрат.

QUOTE
Няма наследяване ... oh thank god

Имаш интерфейси. В С++ това поведение се емулира с виртуални класове.

QUOTE
леле колко е яко всичкия Rust код да е еднакъв... има си едни идиоматики и изобщо не държа да се чувствам като голям човек с тоя C++

Я пробвай в една програма да имаш две библиотеки със синхронен и несинхронен код. icon_wink.gif Дай още време на езика.

QUOTE
Safety-то

И аз мисля, че поведението на компилатора и езика по подразбиране е по-хубаво в Ръст. Имаше риск и в С++ да станат подобни нещата, затова комитета изрично "отслабва" предложения в новите стандарти за да поддържа UB.

QUOTE
Microsoft докладват, че Rust екипите стават най-продуктивните екипи...

Да им дадем малко време да се посменят кадрите и да ги питаме пак. icon_smile.gif

П.п.
И след коментара си виждам, че има нова версия на ГЦЦ. А в промените пише:
QUOTE
{0} initializer in C or C++ for unions no longer guarantees clearing of the whole union (except for static storage duration initialization), it just initializes the first union member to zero. If initialization of the whole union including padding bits is desirable, use {} (valid in C23 or C++) or use -fzero-init-padding-bits=unions option to restore old GCC behavior.

icon_mad.gif
https://gcc.gnu.org/gcc-15/changes.html

Това мнение е било редактирано от SuN на 25-04-2025, 15:50


--------------------
Само аз не троля.
Всички коментари са плод на художествена измислица и нямат общо с действителни и недействителни лица, събития и факти.
PMEmail Poster
Top
dvader
Публикувано на: 25-04-2025, 15:53
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



QUOTE (Дон Реба @ 25-04-2025, 13:30)
ако не си забелязал, if(!(f=fopen()))return 0; е по-малко писане от try-catch, отделно че самото наличие на ексепшън механизъм е причината разни функции да крашват ако им подадеш невалиден файл. замислял ли си се, защо вин32 апитата НЕ крашват ако им дадеш невалиден хендъл? например SetWindowText(0,"proba"); няма да крашне, докато fwrite крашва. причината е че вин апито е старо и е писано на паскал, преди да има ексепшъни. това му поведение е по стандарт заложено, апитата почнаха да крашват чак когато се въведоха ексепшъните. т.е. ексепшъните ти "оправят" проблем който самите те създадоха

Точно за това иде реч - НЕ Е по-малко писане, защото ще пишеш if (0 == на *всяка* функция по веригата - fopen, fread и накрая на fclose. И в случай, че ползваме кодове за грешки, всяка от тези проверки ще върне кодът за грешка на по-горното ниво, където ще пише нови if (0 == и ще връщаш кодове на още по-горно ниво.
С изключенията нещата не се правят така - try/catch блока се слага на най-горното и хваща *всичките* throw по веригата. Разглеждай try/catch като pubslish/subscribe архитектура а всеки throw - като notify icon_smile.gif

Дали трябва да крашва функцията при неправилни данни зависи от това дали трябва да крашва или не icon_smile.gif
Например, strlen(nullptr) ще крашне, lstrlenA(nullptr) няма - коя от двете се държи правилно? icon_smile.gif
Освен това, винапитата крашват като слънце - лично съм правил BSOD на Windows 2000 с ReadFile(). Само че това по-скоро беше бъг, в ХР вече не минаваше номера.
Ако имаш предвид краш на някое АПИ *без* BSOD то това ще опре до въпросът какво наричаме WINAPI. Но дори и в този случай, можеш ли да кажеш пример за такова АПИ? Знам само АПИ-та, които си хвърлят изключения вътрешно (и се виждат само на дебъгер) което не знам дали можем да го наречем краш. Не на последно място fwrite не е WINAPI.

Проблемът с изцепшъните е друг - не са част от ABI-то, което значи, че не можеш да ги ползваш между модули написани на различни езици и дори на различни компилатори на един език. Ако обаче си компилираш всичко от и до и получаваш едно ЕХЕ, тогава са много по-удобни.

PS.
WINAPI от край време има RaiseException icon_smile.gif


--------------------
I find your lack of faith disturbing
PM
Top
ici
Публикувано на: 25-04-2025, 17:23
Quote Post


Group Icon
Име: Ивайло Илчев
Група: 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.
PMEmail PosterUsers Website
Top
dvader
Публикувано на: 25-04-2025, 18:49
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



QUOTE (ici @ 25-04-2025, 17:23)
Тоя прост трик ти увличава кода с около 40%, а стека четири пъти

А тези цифрички са откъде?

За 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
PM
Top
Bender++
Публикувано на: 25-04-2025, 19:58
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 608
Регистриран на: 18.04.21



QUOTE
Ъхъ, и сега пък като гламав ще трябва на всеки ред проверявам дали нещо някъде не ми е върнало грешка.

Holy Rust не e Golang, и този проблем го няма

QUOTE
За какво ти е, нали можеш да напишеш ...

icon_lol.gif icon_eek.gif icon_lol.gif icon_eek.gif

Нямаш ли хубава билд система, нямаш нищо. Даже умрялата билдсистема в голанг е по-добре от цмаке

QUOTE
щото дори не мога да си представя как *езика* може да го следи

правилата на езика правят невъзможни race conditions в safe rust. Винаги може в unsafe с raw pointers да намажеш нещата icon_smile.gif, но това е важно за по-умелите разработчици които пишат библиотеки на по-ниско ниво. За 99.9% от случаите го няма като проблем

QUOTE
Аз пиша ембедед Ц, някъде 90% от времето, за АРМ Кортекс-М. Рънтайма който се използва - Newlib nano, е компилиран без поддръжка на изцепшъни и всеки такъв в крайна сметка стига до фукция _exit(), която, ако не си я заменил е просто безкраен цикъл или място дето се рестартира МЦУ-то.

това в ръст му казваме panic_handler и за ембеддед имаш няколко опции - безхраен цикъл, halt на цпу-то, etc.

QUOTE
Имаш функция panic, която убива програмата. Линус много се кара на на ентусиастите, които искаха да пишат драйвери на Ръст за тази глупост. Каза им да си пренапишат стандартната библиотека или да спрат.

Нуждите на user-space & kernel space са различни

Това мнение е било редактирано от Bender++ на 25-04-2025, 20:01


--------------------
Слава на Цар Путин! Долу украинските фашисти!
PMEmail Poster
Top
dvader
Публикувано на: 25-04-2025, 21:34
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



QUOTE (Bender++ @ 25-04-2025, 19:58)
правилата на езика правят невъзможни race conditions в safe rust.

Как става номера?
Питам съвсем сериозно, щото подозирам, че просто са вградили статичен анализатор в езика.


--------------------
I find your lack of faith disturbing
PM
Top
Bender++
Публикувано на: 25-04-2025, 23:37
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 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:

CODE

fn main() {
   // Create a String, which is heap-allocated and owned by s1
   let s1 = String::from("hello");
   println!("s1: {}", s1); // Works: s1 owns the String

   // Move s1 to s2
   let s2 = s1; // Ownership moves to s2; s1 is invalidated
   println!("s2: {}", s2); // Works: s2 now owns the String

   // This will cause a compile-time error
   // println!("s1: {}", s1); // Error: value borrowed here after move
}


Shared & Exclusive references:
CODE

fn main() {
   let mut value = 42; // Mutable variable

   // Shared reference (&i32)
   let shared_ref1 = &value;
   let shared_ref2 = &value; // Multiple shared references are allowed
   println!("Shared ref1: {}, ref2: {}", shared_ref1, shared_ref2); // Prints: 42, 42

   // Exclusive reference (&mut i32)
   let exclusive_ref = &mut value;
   *exclusive_ref += 1; // Modify the value
   println!("Exclusive ref: {}", exclusive_ref); // Prints: 43

   // Cannot use shared_ref1 here while exclusive_ref exists
   // println!("Shared ref1: {}", shared_ref1); // Error: cannot borrow `value` as immutable because it is also borrowed as mutable
}


Rc<T> е смарт reference counted поинтер, който не е Send защото ако се ползва от много нишки еновременно, брояча ще се намаже
CODE

use std::rc::Rc;
use std::thread;

fn main() {

   // data & data_clone ползват един и същ  споделен брояч вътршено
   let data = Rc::new(42);
   let data_clone = Rc::clone(&data);

   // Опитваме се да преместим втораста инстанция в друга нишка (i.e. Send)
   let handle = thread::spawn(move || {
       println!("Value: {}", data_clone); // компилационна грешка - не имплементира Send
   });

   handle.join().unwrap();
}



Sync:
Arc<T> е смарт atomic reference counted поинтер, който е Send защото атомик брояча може безопасно да се модифицира от няколко нишки едновременно

Мутекса е sync, защото имплементацията му се грижи да не се нарушават правилата на езика. Може от колкото си искаш нишки да кажеш lock(), и той ще се погрижи максимум 1 нишка да държи лока във всеки идин момент от времето и по този начин да имаш 0 или 1 mutable референции.

CODE

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {

   let data = Arc::new(Mutex::new(42));
   let data_clone = Arc::clone(&data); // Clone for the thread

   let handle = thread::spawn(move || {
       let mut value = data_clone.lock().unwrap(); // Safely access the value
       *value += 10;
       println!("Value: {}", *value);
   });

   handle.join().unwrap();
   println!("Final value: {}", *data.lock().unwrap());
}



--------------------
Слава на Цар Путин! Долу украинските фашисти!
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (8) 1 [2] 3 4 ... последна » Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0