Wpis z mikrobloga

Nie jestem zawodowcem, o ile się orientuję, to jednym z większych problemów z C++ jest to, że nie ma kontroli zarządzania pamięcią ani w formie sprawdzenia przy kompilacji ani jako garbage collector. Co stoi na przeszkodzie dodania sprawdzania w czasie kompilacji jak np w Rust? Na przykład w formie opcji, ktoś chce się upewnić to włącza sprawdzenie przy kompilacji, jak nie to zostaje przy starym kompilatorze. Trochę to wydłuży kompilację, ale wydajność programu nie spadnie, więc w czym problem?

#programowanie #naukaprogramowania #cplusplus #cpp #informatyka #rustlang
  • 16
@Goglez: okay więc odnośnie memory safety zobaczym czym jest RAII (resource acqistion is initilization), co nie jest wymuszane przez język ale jest dobrą praktyką i efektywnie daje ci garbage collection jak kończy się życie scope'a w którym jest obiekt,
RAII efektywnie jest wymaszane w języku Rust i tam jest dużo sprawdzania wbudowanego w kompilator
@Goglez: W nowoczesnym C++ problemy z kontrolą pamięci praktycznie nie występują.


@OskarDw: Google twierdzi inaczej i ma na to dość mocne dowody. Generalnie w C++ możesz łatwo strzelić UB nawet używając zwykłych typów z STLa. Nie trzeba nawet do tego wskaźników ani zarządzania pamięcią.
Co stoi na przeszkodzie dodania sprawdzania w czasie kompilacji jak np w Rust?


@Goglez: Niedostatecznie ekspresywny system typów w C++, który nie rozumie pojęcia czasu życia wartości. Musiałbyś robić analizę całego programu a to z kolei nie jest możliwe ze względu na specyficzny sposób budowania projektowe C++ gdzie pliki są kompilowane osobno.
jednym z większych problemów z C++ jest to, że nie ma kontroli zarządzania pamięcią ani w formie sprawdzenia przy kompilacji ani jako garbage collector


@Goglez: nie powiedziałbym że to problem, raczej cechą gdzie pamiecią zarządza programista, co też ma wiele zalet.

Jeśli chcesz żeby pamięć zwalniała się sama możesz to zrobić - choćby licząc referencje. Natomiast oczywiście wymaga to pewnej higieny pisząc kod, bo w C++ zawsze możesz sobie zapamiętać wskaźnik
@Goglez są takie opcje jak np address sanitizer itp, ale są to wytwory poboczne, poza standardem. Rust z filozofii ma wbudowane mechanizmy, które maja zapobiegać leakom i tym podobnym akcjom. W tym "nowocześniejszym" c++ standard dodał już pewne mechanizmy jak smart pointery i ogólnie RAII, ale z doświadczenia wiem, że nadal są z tym problemy bo są kobyły operujące na raw pointerach gdzie czasem coś trzeba modyfikować. Wówczas pozostaje mieć w pipelinie
@Krolik: Wklej proszę te dowody


@OskarDw:

Google zaobserwował duży spadek liczby błędów w nowym kodzie odkąd zmienił C++ na Rust jako główny język rozwoju Androida:
https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html?m=1

Microsoft doszedł wcześniej do podobnych wniosków: https://visualstudiomagazine.com/articles/2019/07/18/microsoft-eyes-rust.aspx?m=1

70% dziur bezpieczeństwa to błędy zarządzania pamięcią.

Mechanizmy bezpieczeństwa w C++ są dość mocno prowizoryczne i niczego nie gwarantują. Np. taka prosta różnica - const correctness. W C++ jak masz const referencję to wcale nie ma gwarancji
Google zaobserwował duży spadek liczby błędów w nowym kodzie odkąd zmienił C++ n


@Krolik: ten sam google w swoich projektach nie wdraża nowych rozwiązań z c++ (i nie mówię tu o świeżynkach), bo chcą zachować kompatybilność ze starym kodem. Widocznie wolą od nowa przepisywać do rusta niż uwspółcześnić starszy kod,.

jednym z większych problemów z C++ jest to, że nie ma kontroli zarządzania pamięcią [...] jako garbage collector


@Goglez: i
i całe szczęście że GC nie ma.


@zetisdead: Gwoli ścisłości - GC jest opcjonalne - istnieją crate'y które implementują tracing GC. GC się przydaje w implementacjach struktur lockless. Tylko że takie GC jest lokalne dla struktury danych i dzięki temu nie ma wad globalnego GC - nie powoduje pauz, nie ma też tak dużego narzutu pamięciowego.

ten sam google w swoich projektach nie wdraża nowych rozwiązań z c++


Problem w tym,
@Krolik: Dość słabe dowody, nie wiemy w jakim standardzie C++ te błędy były.

taka prosta różnica - const correctness. W C++ jak masz const referencję to wcale nie ma gwarancji że się wskazywany obiekt nie zmieni.

To jest prawda, Rust jest bezpieczniejszy, ale to o czym wspominasz to są drobnostki. Wyprodukowanie kodu, który zmienia const referencje to jest dość trudne zadanie, zgaduję, że łatwiej coś popsuć w sekcji "unsafe" w Rust.
Wyprodukowanie kodu, który zmienia const referencje to jest dość trudne zadanie


@OskarDw: A kto powiedział, że mam zmieniać const referencję? Wystarczy zmienić ten sam obiekt używając innej referencji, która nie jest const. Jest to sytuacja bardzo łatwa do uzyskania przez przypadek, w dużym projekcie, składającym się z wielu komponentów. Const nie mówi o tym, że obiekt się nie zmieni. Const mówi o tym, że jedynie Ty nie możesz zmienić obiektu. Niestety
@OskarDw: Po pierwsze obecnie 99% softu jest wielowątkowa. Po drugie wielowątkowość też nie jest konieczna aby zrobić sobie niespodziankę. Wystarczy że wywołasz metodę komponentu, który ma zwykłą referencję do tego samego co Ty masz const-referencję i już możesz mieć "spooky action at a distance". Co się też może zakończyć UB, wystarczy że Twoja const-referencja jest do elementu wektora, wektor niby masz const, więc zakładasz że jest bezpiecznie, a tu coś innego