-
11. Data: 2019-05-07 21:15:04
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Wojciech Muła <w...@g...com>
On Wednesday, April 17, 2019 at 8:43:22 PM UTC+2, Szyk Cech wrote:
> Inna sprawa, że F-35-coding-rules.pdf wprowadza takie ograniczenia, że z
> tego C++ zostaje może 25% przez co programowanie zgodnie z tymi
> zaleceniami jest bardziej prymitywne niż w latach 90 XXw (czyli z przed
> standaryzacji C++). Widać, że ktoś bardzo lubił Ada-ę i pomyślał, że w
> zasadzie można by tak samo programować w C++.
Nie, ktoś znał bardzo dobrze C++ i wywalił wszystkie niebezpieczne
i błędogenne konstrukcje. C++ zachęca do pisania w stylu "write
once, debug endlessly", co się słabo sprawdza przy sterowaniu
maszyną wartą sześcio-, czy siedmiocyfrową kwotę.
Zadanie dla chętnych: w ilu miejscach może tu polecieć wyjątek?
Type1 i Type2 to jakieś klasy dostarczone przez użytkownika,
nic o nich nie wiemy.
Type1 fun(Type2 a, Type2 b)
{
if (a.get_value() > b.get_value()) {
return a.get_foo();
}
return a.get_bar() + b.get_foo();
}
w.
-
12. Data: 2019-05-07 21:38:29
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Szyk Cech <s...@s...pl>
> Zadanie dla chętnych: w ilu miejscach może tu polecieć wyjątek?
Kogo to obchodzi? Moje (proste i sprawdzone w praktyce w programowaniu w
C++ z Qt od 10 lat) zasady obsługi wyjątków są takie:
1. Każda klasa wyjątku dziedziczy po std::exception (tego przestrzegają
też klasy wyjątków Qt),
2. Obstawiamy funkcję main czymś takim:
#define MAIN_CONSOLE_CATCH \
catch(Exception& aEx) \
{ \
QTextStream lErr(stderr); \
lErr << QObject::tr("Exception occurs! Sender: %1, Error code:
%2\nMessage:\n%3").arg(aEx.senderName()).arg(aEx.err
orCode()).arg(aEx.what()).toUtf8()
<< endl << flush; \
return EXIT_FAILURE; \
} \
catch(std::exception& aEx) \
{ \
QTextStream lErr(stderr); \
lErr << QObject::tr("Exception
occurs!\nMessage:\n%1").arg(aEx.what()).toUtf8() << endl << flush; \
return EXIT_FAILURE; \
} \
catch(...) \
{ \
QTextStream lErr(stderr); \
lErr << QObject::tr("Unknown exception occurs!") << endl <<
flush; \
return EXIT_FAILURE; \
}
3. Obstawiamy wszystkie funkcje obsługi zdarzeń
4. Obstawiamy wszystkie funkcje wątków, obie czymś takim:
#define STANDARD_CATCH \
catch(Exception& aEx) \
{ \
gCritical(QObject::tr("Exception occurs!\n%1").arg(aEx.what()),
aEx.senderName(), static_cast<quint64>(aEx.errorCode())); \
} \
catch(std::exception& aEx) \
{ \
gCritical(QObject::tr("Exception occurs!\n%1").arg(aEx.what()),
QObject::tr("Unkonwn"),
static_cast<quint64>(EnergoKodTools::eErrorCode::eUn
known)); \
} \
catch(...) \
{ \
gCritical(QObject::tr("Unknown exception occurs!"),
QObject::tr("Unkonwn"),
static_cast<quint64>(EnergoKodTools::eErrorCode::eUn
known)); \
}
Gdzie gCritical jest czymś takim:
inline void gCritical(QString aText, QString aSender, quint64 aErrorCode)
{
Errors::instance()->error(aText, eErrorType::eCritical, aSender,
aErrorCode);
gMessage(QMessageBox::Critical, QObject::tr("Critical"), aText,
QStringLiteral("Error: %1\nModule: %2\nCode:
%3").arg(aText).arg(aSender).arg(aErrorCode));
}
Errors to klasa "silnik", singleton zbierania błędów (do ew.
wyświetlenia i ew. zaraportowania).
A gMessage to:
inline void gMessage(QMessageBox::Icon aIcon, QString aShortText,
QString aInformativeText, QString aDetailedText = QStringLiteral(""))
{
QTextStream lErrStream(stderr);
lErrStream << QObject::tr("%1
%2\n%3").arg(qApp->applicationName()).arg(aShortText
).arg(aInformativeText);
if(!aDetailedText.isEmpty())
lErrStream << endl << aDetailedText;
QMessageBox lMessage;
lMessage.setText(aShortText);
lMessage.setInformativeText(aInformativeText);
lMessage.setDetailedText(aDetailedText);
lMessage.setIcon(aIcon);
lMessage.exec();
}
I wtedy wszystko jest proste...
-
13. Data: 2019-05-07 22:52:10
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: heby <h...@p...onet.pl>
On 07/05/2019 21:15, Wojciech Muła wrote:
> Zadanie dla chętnych: w ilu miejscach może tu polecieć wyjątek?
> Type1 i Type2 to jakieś klasy dostarczone przez użytkownika,
> nic o nich nie wiemy.
>
> Type1 fun(Type2 a, Type2 b)
> {
> if (a.get_value() > b.get_value()) {
> return a.get_foo();
> }
>
> return a.get_bar() + b.get_foo();
> }
Skoro nic o nich nie wiemy to obsługa tego wyjątku ma znaleźć się w
kodzie który coś o Type1 i Type2 wie czyli pewnie poziom niżej. Inaczej
kończysz na try {} catch(...) to jest jeszcze gorsze.
Wyjątki nie łapie się po każdym dodawaniu. Łapie się tam gdzie wiadomo
co z nimi zrobić.
-
14. Data: 2019-05-08 07:54:51
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Maciej Sobczak <s...@g...com>
> Wyjątki nie łapie się po każdym dodawaniu. Łapie się tam gdzie wiadomo
> co z nimi zrobić.
Bardzo dobrze.
Problem tylko w tym, że bardzo rzadko wiadomo, co z nimi zrobić. Często sprowadza się
to do pokazania użytkownikowi komunikatu o błędzie. Albo do wrzucenia go do logu. Oba
te przypadki nie mają zastosowania w systemach krytycznych takich jak sterowanie
samolotem.
W szczególności, standard kodowania dla tego samolotu w ogóle zabrania używania
wyjątków.
--
Maciej Sobczak * http://www.inspirel.com
-
15. Data: 2019-05-08 15:32:30
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Wojciech Muła <w...@g...com>
On Tuesday, May 7, 2019 at 10:52:14 PM UTC+2, heby wrote:
> On 07/05/2019 21:15, Wojciech Muła wrote:
> > Zadanie dla chętnych: w ilu miejscach może tu polecieć wyjątek?
> > Type1 i Type2 to jakieś klasy dostarczone przez użytkownika,
> > nic o nich nie wiemy.
> >
> > Type1 fun(Type2 a, Type2 b)
> > {
> > if (a.get_value() > b.get_value()) {
> > return a.get_foo();
> > }
> >
> > return a.get_bar() + b.get_foo();
> > }
>
> Skoro nic o nich nie wiemy to obsługa tego wyjątku ma znaleźć się w
> kodzie który coś o Type1 i Type2 wie czyli pewnie poziom niżej. Inaczej
> kończysz na try {} catch(...) to jest jeszcze gorsze.
>
> Wyjątki nie łapie się po każdym dodawaniu. Łapie się tam gdzie wiadomo
> co z nimi zrobić.
Ale łapanie wyjątku to jest połowiczne rozwiązanie problemu. W szczególności,
jeśli wyjątek może pójść w dowolnym miejscu kodu (w tym przykładzie jest co
najmniej 13 miejsc, skąd może coś polecieć), to jaki będzie stan obiektu na
rzecz którego wołano metodę? Czy np. taki obiekt można bezpiecznie używać
dalej (stan wewnętrzny pozostał spójny)? Albo chociaż wywołać destruktor?
A co jeśli wyjątek leci z miejsca, o którym wierzyłeś, że nigdy nie poleci
i jednak dostajesz terminate?
w.
-
16. Data: 2019-05-08 19:31:59
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: heby <h...@p...onet.pl>
On 08/05/2019 07:54, Maciej Sobczak wrote:
>> Wyjątki nie łapie się po każdym dodawaniu. Łapie się tam gdzie wiadomo
>> co z nimi zrobić.
> Bardzo dobrze.
To jakiś egzamin?
> Problem tylko w tym, że bardzo rzadko wiadomo, co z nimi zrobić.
I jaki to ma związek z narzekaniem na jezyk C++?
> Często sprowadza się to do pokazania użytkownikowi komunikatu o błędzie.
Nie wiem co to znaczy "często", ale u mnie raczej nie.
> Oba te przypadki nie mają zastosowania w systemach krytycznych takich jak
sterowanie samolotem.
Ale przecież przykład miał służyć marudzeniu o bezdennnym dziadostwie C++.
> W szczególności, standard kodowania dla tego samolotu w ogóle zabrania używania
wyjątków.
Standardy kodowania zawiarają dużo więceń wykluczeń, wiele z nich
generuje po stronie programisty emulacje zachowań wykluczonych.
Taki mały przykłąd z systemu krytycznego:
return a() && b() && c() && d() ... ;
To jest emulacja wyjątku w środowisku gdzie wyjątków ma nie być. Wyszło
jak zwykle. Parcie na systemy ograniczone wcale nie generuje lepszego
jakościowo kodu, co najwyżej generuje kod który lepiej ogarnia się
formalną weryfikacją a i to jest mocno naciągane.
-
17. Data: 2019-05-08 19:51:36
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: heby <h...@p...onet.pl>
On 08/05/2019 15:32, Wojciech Muła wrote:
> Ale łapanie wyjątku to jest połowiczne rozwiązanie problemu. W szczególności,
> jeśli wyjątek może pójść w dowolnym miejscu kodu (w tym przykładzie jest co
> najmniej 13 miejsc, skąd może coś polecieć), to jaki będzie stan obiektu na
> rzecz którego wołano metodę?
Taki w jakim paradygmacie napisałeś kod. Mogłeś napisać pure function,
mogłeś napisać kod z oparciem o transakcje z RAII, mogłeś totalnie sp...
i napisać kod bazujacy na sideeffectach globalnych. Przecież jest wybór
i akurat C++ pozwala napisać kod cholernie bezpiecznie i cholernie
niebezpiecznie na raz. Ba, lisp też i ada też. To się załatwia code
review i kilkoma developerami w zespole którzy potrafią zrozumieć na
pisać kod aby nie trzeba było go debugować "endlessly" a to czy to C++
nie jest jakoś specjalnie istotne bo każdy język jest Turing-complete
wiec poziom spieprzenia można osiągnąć identyczny.
Przedstawiona funkcja jest generyczna. Jeśli by ta funkcja miała
dodatkowo zajmować się ogarnianiem stanu swoich argumentów wejściowych i
łapaniem bilionów detalicznych exceptionów a nastepnie szukaniem w
szklanej kuli co z nimi zrobić to niestety ale taki programista nie ma
racji bytu w dowolnej branży bo to najzwyczajniej spieprzony kod jest i
to w najgorszy możliwy sposób.
> Czy np. taki obiekt można bezpiecznie używać
> dalej (stan wewnętrzny pozostał spójny)?
Nigdy tego nie wiesz. Ale AKURAT ten znienawidzony C++ ma całkiem
przyzwoite metody ograniczania działania sideeefectów jak scope i RAII.
Po ich uzyciu jestem w stanie kontrolować sideeefecty znacząco wygodniej
niż w innych językach imperatywnych, w sytuacjach krytycznych. Tylko że
można też pisać kod funkcyjnie i tego nie robić. Masz wybór.
No tak, zapomniałem że standarny produkcji automatyki do dildo
zabraniają używania RAII, pętli while, tabulacji i nieparzystych
wartości inta.
Ariane pokazało że wybranie Ady nie powoduje że ludzie piszą kod
bezpiecznie, dalej pisali w asemblerze. Nie wybór języka jest istotny
tylko programisty. Wybrali hackerów, mają kupę a nie bezpieczny kod bez
względu na koszerność języka.
> Albo chociaż wywołać destruktor?
Zawsze wywoła destruktor, *ZAWSZE* za wyjątkiem przypadku buga w
kompilatorze. Chyba że lubisz longjmp. Widziałem już w "krytycznie
bezpiecznym kodzie" wiec idiotów nie brakuje.
> A co jeśli wyjątek leci z miejsca, o którym wierzyłeś, że nigdy nie poleci
> i jednak dostajesz terminate?
To wykrywam to w unit testach i poprawiam buga. Ostatecznie ktos umiera
bo mu rozrusznik nie zadziałał. Boeing nie ma z tym dzisiaj jak widać
problemu, Toyota nie miała ze swoim pedłem gazu itd itp. Najzwyczajniej
nie da się ogarnąć systemu mającego kilka tyś lini kodu formalnie a
pojedyncze przypadki kiedy się to udało, jak L4, są raczej
potwierdzeniem że wymaga to nadludzkiego wysiłku. A zakładanie że pisze
się kod bez bugów jest absurdem. Jesteśmy zbudowani z białka i nic na to
nie poradzimy choć potrafimy to znacząco poprawiać używając inżynierii
(o)programowania znanej od lat co najmniej 60. Ani Toyota ani Ariane nie
są przykładem używania tych technik bo w obu wypadkach można było je
zasymulować wcześniej invitro.
A co sie stanie jak w ten kod trafi meteoryt z Neptuna? Jesteś na to
przygotowany?
-
18. Data: 2019-05-09 08:04:43
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Maciej Sobczak <s...@g...com>
> > Bardzo dobrze.
>
> To jakiś egzamin?
A jakbym normalnie i zgodnie z grupowymi zwyczajami zawalił Cię bluzgami, to by nie
był? :-)
> > Problem tylko w tym, że bardzo rzadko wiadomo, co z nimi zrobić.
>
> I jaki to ma związek z narzekaniem na jezyk C++?
Myślałem, że narzekamy na standard kodowania. Zakaz używania wyjątków jest dosyć
uniwersalny, niezależny od języka.
> > Często sprowadza się to do pokazania użytkownikowi komunikatu o błędzie.
>
> Nie wiem co to znaczy "często", ale u mnie raczej nie.
Interesujące. Ale to może (!) oznaczać, że obsługujesz wyjątki relatywnie blisko ich
wystąpienia.
> Ale przecież przykład miał służyć marudzeniu o bezdennnym dziadostwie C++.
Właśnie zgubiłem się, co hejtujemy. Jeśli C++, to niesłusznie (co za niespodzianka!),
bo zakaz wyjątków jest niezależny od języka.
> Taki mały przykłąd z systemu krytycznego:
>
> return a() && b() && c() && d() ... ;
>
> To jest emulacja wyjątku w środowisku gdzie wyjątków ma nie być. Wyszło
> jak zwykle. Parcie na systemy ograniczone wcale nie generuje lepszego
> jakościowo kodu, co najwyżej generuje kod który lepiej ogarnia się
> formalną weryfikacją a i to jest mocno naciągane.
Niezupełnie. W takich systemach może być wymaganie na pokrycie testami każdej
ścieżki. Jeżeli są wyjątki, to tych ścieżek nawet nie widać a rozstrzygnięcie
automatyczne ile ich jest i gdzie może wymagać dostępu do całego kodu i nawet wtedy
może być nierealne. Natomiast użycie iloczynu logicznego tak jak powyżej, chociaż
wątpliwe stylistycznie, jest jednak lokalne - tzn. analizę wszystkich ścieżek da się
zrobić w ramach tylko tego wyrażenia. Wtedy znacznie łatwiej spełnić wymaganie
pokrycia testami.
Dlatego nie zgadzam się z określeniem "wyszło jak zwykle". Ten przykład da się
obronić. Stylistycznie słaby (subiektywnie), ale broni się na poziomie procesu.
--
Maciej Sobczak * http://www.inspirel.com
-
19. Data: 2019-05-09 08:21:33
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Maciej Sobczak <s...@g...com>
> Ariane pokazało że wybranie Ady nie powoduje że ludzie piszą kod
> bezpiecznie, dalej pisali w asemblerze. Nie wybór języka jest istotny
> tylko programisty.
Też nie. Tzn. programiści lubią wierzyć w swoją wyjątkowość, ale przedstawione przez
Ciebie przykłady (Ariane, Toyota, Boeing) akurat wskazują na błędy w zarządzaniu i w
wymaganiach. Programista może być perfekcjonistą, ale perfekcyjnie zaimplementowane
złe wymagania albo system złożony do kupy z niewłaściwych komponentów i tak będą się
rozpadać i zabijać.
Procesy jakościowe (o ile są przestrzegane) w ogóle nie zakładają, że programista
będzie perfekcyjny. Wręcz przeciwnie - założenie jest właśnie takie, że programista
spieprzy wszystko, co się da. Jakość wynika z procesów integralnych (z weryfikacji) a
nie z deweloperskich. Pytanie, czy takie procesy integralne są. Problem w tym, że
łatwo z nich zrezygnować.
> Wybrali hackerów, mają kupę a nie bezpieczny kod bez
> względu na koszerność języka.
Wybór języka wpływa na to, jak łatwo jest coś spieprzyć. A ponieważ zakładamy, że
programista spieprzy wszystko co może, to wybór języka jest ważny. Żeby mógł
spieprzyć jak najmniej.
> > A co jeśli wyjątek leci z miejsca, o którym wierzyłeś, że nigdy nie poleci
> > i jednak dostajesz terminate?
>
> To wykrywam to w unit testach i poprawiam buga.
Unit testy nie wykrywają wyjątków. Chyba że mamy inne rozumienie tego terminu.
> A co sie stanie jak w ten kod trafi meteoryt z Neptuna? Jesteś na to
> przygotowany?
Jeśli takie są wymagania, to powinien być.
--
Maciej Sobczak * http://www.inspirel.com
-
20. Data: 2019-05-09 11:32:25
Temat: Re: Ada Tutorial - w Instytucie Lotnictwa
Od: Roman Tyczka <n...@b...no>
On Tue, 7 May 2019 12:15:04 -0700 (PDT), Wojciech Muła wrote:
> Zadanie dla chętnych: w ilu miejscach może tu polecieć wyjątek?
> Type1 i Type2 to jakieś klasy dostarczone przez użytkownika,
> nic o nich nie wiemy.
>
> Type1 fun(Type2 a, Type2 b)
> {
> if (a.get_value() > b.get_value()) {
> return a.get_foo();
> }
>
> return a.get_bar() + b.get_foo();
> }
>
> w.
Ja tak z ciekawości, bo napisałeś dalej, że jest tych miejsc 13, czy
mógłbyś je wskazać? Nie programuję w C++, więc widzę tylko możliwość
wysypki w wywołaniach metod (zarówno w nich samych jak i na ich braku czyli
nilu). Ale z tego i tak nie wyjdzie aż 13. Czy masz tu na myśli jeszcze
przeciążanie operatorów? Co jeszcze?
--
pozdrawiam
Roman Tyczka