🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #267862

Re: Ciemna strona C++

#267862
From: Sektor van Skijlen
Date: Tue, 11 Dec 2007 19:24
707 lines
31817 bytes
Dnia Wed, 05 Dec 2007 14:34:36 +0100, Sebastian Kaliszewski skrobie:
> Sektor van Skijlen wrote:
> >>>>>>[ o listach]
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>>>, jest lepiej 
> >>>>>>>>wpasowana do języka
> >>>>>>>
> >>>>>>>Nie wydaje mi się, że lepiej.
> >>>>>
> >>>>>>LOL, W pythonie lista ma reprezentację w samej składni.
> >>>>>
> >>>>>I to ma niby świadczyć o lepszym wpasowaniu do języka?
> >>>
> >>>>Ddaj do tego for, składnię dla splajsów, itd...
> >>>
> >>>... która dobrze prezentuje się w tutorialach, ale w praktyce nie ma
> >>>różnicy, czy ten lukier składniowy jest, czy nie?
> > 
> >>Lukier skłądniowy toi jest właśnie element "wpasowania do języka"
> > 
> > To chyba mamy inne definicje pojęcia "wpasowania do języka".
> > 
> > Może chodziło ci o "zawarcie w definicji języka"?

> Nie, nie chodziło. Chodzi o to, że w Pythonie masz a = [1, 2, 3]
> a w C++ masz:
> std::list a;
> a.push_back(1);
> a.push_back(2);
> a.push_back(3);

Super - ale (skoro, jak mówisz, w Pythonie jest dużo fajnych zbiorników) czy
można tak inicjalizować również dowolny, napisany przez siebie zbiornik?

Jeśli nie, to nic to dla mnie nie znaczy, bo w C++ też mogę napisać:

int a [] = { 1, 2, 3 };

i też stwierdzić, że "jakiś" zbiornik jest dobrze wpasowany do języka.

> >>>>>WSZYSTKIE języki skryptowe mają takie właśnie "wsparcie językowe" do tzw.
> >>>>>list, bo jest to w tych językach podstawowy i niemalże jedyny zbiornik.
> >>>
> >>>>Nie jedyny. Tu masz jeszcze tuple, słownik i zbiór -- czyli cały podstawowy 
> >>>>zestaw. W bibliotece masz jesczcze następne (np talię).
> >>>
> >>>Ach i och. Perl i Tcl jako tuple wykorzystują ten swój podstawowy zbiornik,
> >>>zwany (akurat w obu) listą.
> > 
> > 
> >>Och i ach. Python nie.
> > 
> > No to ma problem na własne życzenie. Żaden z języków skryptowych "starej
> > szkoły" takich debilizmów nie robi.

> Sektor zamiast chrzanić, przeczytaj sobie jaka jest różnica. Zostawiam jako 
> zadanie domowe :)

Ha ha ha. Wielka mi różnica, że tupli nie mogę modyfikować! I to w języku, w
którym i tak nawet głupiego consta nie da się zrobić.

> > Tego typu podejście jest pożądane tylko w
> > językach, które mają większe rygory bezpieczeństwa, ale one sprawdzają to i
> > tak w czasie kompilacji (bo sprawdzanie tego w czasie wykonywania to pic na
> > wodę).

> Bzdura.

Bo nie masz nic więcej do powiedzenia?

> >>>>Tylko czemu interfejs jest tak parszywie niejednolity? begin/end to trochę mało.
> >>>
> >>>Jak to niejednolity! Jest cholernie jednolity.
> > 
> >>Ależ skąd. Jednolite w miarę są pary vector i deque, map i multimap oraz set 
> >>i multiset.
> > 
> > A co jest niejednolitego w vector i list?

> Wszystko.

"Wszystko" to znaczy "nic" albo "nie wiem".

> >>map wyłazi zupełnie z jej iteracją po parach. list jest w ogóle 
> >>w poprzek, itd...
> > 
> >>O jakiś spójnych gwarancjach już lepiej nie myśleć.
> > 
> > Nie rozumiem nadal. Nie podałeś ani jednego konkretu. Opisanie które zbiorniki
> > są twoim zdaniem niejednolite nic nie znaczy.

> popatrz sobie na interfejs list i vector. Zrób mi vector::sort(), czy 
> vector::splice(whatever) list::at, itd...

To ty do tej pory nie wiesz o tym, że do zbiorników swobodnego dostępu należy
stosować algorytm introsort (czyli std::sort), a do zbiorników dwukierunkowych
algorytm mergesort (czyli std::stable_sort), a list::sort jest to to samo co
std::stable_sort, tylko zaimplementowany w sposób bardziej specjalizowany
(stable_sort, tak jak sort, wykonywałby kopie wartości, a list::sort po prostu
przestawia węzły na żywca)?

Lista ma zaimplementowane wewnętrznie te rzeczy, które się tak zaimplementować
opłacało ze względu na jej szczególności i specjalizację.

To nie jest kwestia spójności zbiorników. To jest kwestia koncepcji, jakie te
zbiorniki spełniają (polecam dokumentację do STL-a). Lista nie spełnia
koncepcji zbiornika swobodnego dostępu, a jedynie zbiornika dwukierunkowego, a
koncepcja zbiornika dwukierunkowego nie zawiera operator[] ani metody at().

Czy to jest takie trudne do zrozumienia?

O tym, czy taki podział na koncepcje jest słuszny, możemy dopiero porozmawiać,
jak będziesz wiedział, jak należy postawić problem.

> lista z C++ jest wyjątkowo do dupy. Ponawtykali jakiś rzeczy których nie 
> powinno być (sort, merge, itp...)

I bardzo słusznie zrobili - na tej samej zasadzie, na jakiej vector posiada
metodę reserve(), a list nie.

Może twoim zdaniem powinny one mieć wszystkie te same metody, wszystkie te
same zależności, wszystkie te same wymagania, a nawet jeszcze niech mają taką
samą implementację. Wtedy będą spójne. A nie, cholera, będą miały inne nazwy.

> >>>Do tego stopnia, że nie da się
> >>>zrobić standard-conformant listy jednokierunkowej (pojedynczo wiązanej), a
> >>>niektóre ciołki (jak np. autor języka D) nie rozumie, dlaczego do sprawdzania
> >>>czy string jest pusty trzeba robić if ( s.enpty() ), zamiast normalnie
> >>>if ( s.size() ).
> > 
> >>To dlaczego dla sprawdzenia czy w mapie jest klucz trzeba robić 
> >>m.count(keyVal) zamiast m.has_key(keyVal)? Dlaczego "niektóre ciołki" takie 
> >>jak członkowie komitetu nie rozumieją?
> > 
> > Zastanów się najpierw, o co właściwie pytasz:
> > 1. Dlaczego wybrano nazwę 'count', a nie 'has_key'
> > 2. Dlaczego 'count' nie ma aliasa o nazwie 'has_key'
> > 
> > Mam nadzieję, że pytasz o #2, bo pytanie o #1 jest głupie z zasady.

> 2

> [...]
> > Ja się z tym nie zgadzam, i uważam, że zrobienie funkcji has_key:
> > 
> > bool has_key( const KeyType& k ) { return count( k ) > 0; }
> > 
> > ma jak najbardziej sens, bo nazwa has_key lepiej oddaje intencje, niż count w
> > przypadku std::map i std::set.

> A w przypadku multi_map i multi_set może być nawet (zależnie od samej 
> implementacji kontenera) nieco szybciej szybciej zaimplementowana.

A tu się zgadza - już nawet Seweryn podał implementację, chociaż mam poważne
wątpliwości, czy rzeczywiście jest sensowna.

Tylko że akurat to jest dla mnie głupie. Nie po to pytam, żeby tylko zadać tak
sobie pytanie, tylko dlatego, że chciałbym następnie wykonać na znalezionych
danych jakąś operację - i to dla mnie robi equal_range.

To jest dokładnie taka sama sytuacja, jak to, dlaczego nie ma "zapytania, czy
obiekt o jest typu T". Nie ma, ale za to jest dynamic_cast.

> >>>>>Poza tym nie wiem, dlaczego właściwie uważasz, że vector jest bardziej
> >>>>>uniwersalny, niż list.  To prawda, że vector nadaje się do tzw. "większości
> >>>>>zastosowań", ale ma jedną bardzo paskudną wadę: unieważnienie iteratorów
> >>>>>następuje tam po każdej modyfikacji liczebności zbiornika.
> >>>
> >>>>Po każdej po której zmienia się capacity. capacity zaś zmienia się tylko 
> >>>>czasami.
> >>>
> >>>Weź ty się z łaski swojej nie ośmieszaj, dobrze?
> > 
> >>sam się ośmieszasz. Te gwarancje są po to, by można było określone 
> >>konstrukcje wykonać.
> > 
> > Konkretnie które gwarancje?

> Ważności iteratorów po określonych operacjach.

Ty cały czas nie rozumiesz.

Ile znasz algorytmów, w których ze zbiornika swobodnego dostępu usuwa się
elementy od końca? Ja znam tylko jeden przypadek - tylko wtedy, gdy ten
zbiornik jest stosem.

> >>>>>Miałem właśnie
> >>>>>ostatnio taki przypadek, że musiałem trzymać iteratory do elementów, żeby je
> >>>>>móc szybko usuwać.
> >>>
> >>>>To możesz trzymać indeksy elementów i usuwac po begin()+index.
> >>>
> >>>A, jasne, oczywiście! Usunięcie elementu ze środka też oczywiście nie zmieni
> >>>mi względnego położenia obiektów od tego miejsca w dal.
> >>>
> >>>Czy ty na prawdę tak na siłę chcesz coś udowodnić, że aż nie omieszkasz się
> >>>kompromitować?
> > 
> >>Akurat usuwanie z vectora można robić jadąc od rbegin do rend i robiąc 
> >>zwykłe erase. To jest gwarantowane przez język.
> > 
> > Sebek, do jasnej cholery, mam takie wymagania, że dowolny obiekt ze zbiornika
> > może być usunięty w dowolnym czasie.

> Nie wiem jakie masz wymagania, bo ich nie podałeś. Nie wiem czy usuwasz 
> wszystko na raz, czy też w arbitralnym momencie arbitralny kawałek. Nie 
> podałeś też nawet rzędu wielkości danch.

Przecież napisałem, że chcę je móc w szybki sposób usuwać - nigdzie nie
napisałem, że wszystkie naraz. Sugestia, że chcę używać do czegoś określenia
pozycji w zbiorniku powinna ci była sprawę naświetlić od razu, bo gdybym
chciał usuwać wszystkie naraz, to nie potrzebowałbym żadnej pozycji w
zbiorniku, tylko zrobiłbym normalnie clear(). Czy tego aż tak trudno się
domyślić?

Czemu ty zamiast najpierw zrozumieć dlaczego chcę stosować taki sposób
najpierw usiłujesz mi udowodnić, że go nie potrzebuję?

> > A ty mi tu proponujesz jakieś śmieszne
> > usuwanie od końca?
> > 
> >>Tyle że jest to mało wydajne i nie ma nic wspólnego z szybkim usuwaniem.
> > 
> > To nie ma nic wspólnego z jakimkolwiek usuwaniem, ani z jakąkolwiek mającą
> > sens operacją, jeśli rozpatrujemy przestrzeń rozwiązań przemysłowych, a nie
> > akademickich rozważań.

> W "przestrzeni rozwiązań przemysłowych" dla dużej liczby małych struktur to 
> sie może opłacać (struktury po kilkadziesiąt pozycji których jest wiele -- 
> pomagamy cache locality).

Tak, ale nie stosowane w taki sposób. Jeśli już, to można kombinować z
std::deque, albo czymś podobnym (w sensie, lepiej kontrolowanym).

> >>>>>Podpowiesz mi może, jakiego rozwiązania powinienem użyć w Pythonie?
> >>>
> >>>>wbudowanej listy albo deque -- zależnie co robisz.
> >>>
> >>>Szczegółowo proszę - jak mogę przechowywać wartość, która będzie mi określała
> >>>pozycję elementu w zbiorniku i dopóki ten element będzie w zbiorniku, nie
> >>>zmieni się nigdy po jakiejkolwiek modyfikacji tego zbiornika.
> > 
> >>Zmieniasz wymagania.
> > 
> > 
> > Brnij dalej.
> > 
> > 
> >>PRzy takich użyj słownika i już.
> > 
> > 
> > A, no oczywiście, najlepiej użyć słownika - po co mi stały czas operacji
> > usunięcia elementu, wystarczy przecież logarytmiczny, a konieczna na wszelki
> > wypadek obsługa błędu nie znalezienia elementu to przecież drobny szczegół.
> > Nie wspomnę o generatorze unikalnych kluczy.

> Musz więc gdzieś przechowywać pozycje tych elementów albo masz znowu liniowy 
> koszt usuwania.

Brawo!

I to mi właśnie (stały koszt usuwania, jeśli zapamiętam sobie pozycje, która
nie będzie się zmieniać) zapewnia std::list - i w przypadku std C++ tylko
std::list.

Jeśli każdy istniejący obiekt siedzi w liście, to każdy ma zapisany swój
iterator. W efekcie jestem w stanie każdy z nich usuwać z listy w czasie
stałym.

> > Czyli co mam
> > zrobić, trzymać obiekty połączeń nie usunięte dotąd, aż zbierze się grupa
> > zdechłych połączeń od samego końca wektora, czy też mam przykazać
> > użytkownikom, żeby nie rozłączali połączeń, jeśli po nich jest jeszcze ktoś
> > połączony?
> > 
> > 
> >>>Jak już dyskutujemy, to dyskutujmy konkretnie - jeśli masz jakieś sensowne
> >>>zarzuty, to je poprzyj. Na razie uciekasz w kąt.
> > 
> >>Narazie to ty jesteś nikonkretny.
> > 
> > 
> > Przedstawiłem ci wystarczające minimum wymagań

> Nie. Dopiero teraz coś konkretnego jest, ale i tak mało.

Przestawiłem ci nie wymagania co do działania programu, tylko wymagania co do
zbiornika. Jeśli nie przedstawiłem żadnych szczególnych warunków, przy których
można poszukać odrębnego lub prostszego rozwiązania, to znaczy, że takowych
nie ma.

> > żeby można było pod to
> > podpasować konkretne rozwiązania: chcę mieć zbiornik taki, którego elementy
> > będą miały węzły o stałej pozycji (wyrażanej odpowiednią wartością) nie
> > zmieniającej się w przypadku zmiany liczbności zbiornika (poza usunięciem tego
> > właśnie elementu).
> > 
> > Zbiornik taki, jak np. mapa (słownik) spełnia te wymagania, ale jest od
> > std::list niezaprzeczalnie gorszy, bo:
> > 
> >  - złożoność dostępu jest logarytmiczna
> >  - istnieje potencjalny błąd nieznalezienia elementu
> >  - istnieje konieczność użycia generatora kluczy
> > 
> > Nadal czekam na propozycję rozwiązania tego w tym wszystkowyrażalnym Pythonie.

> To już powiedziałem -- słownik

Jest to - jak powiedziałem - rozwiązanie spełniające, owszem, wymagania (i -
co ciekawsze - w językach skryptowych wszyscy je stosują), niestety słabe w
stosunku do std::list z uwagi na:
 - konieczność generowania kluczy (wartości iteratorów std::list są same z
   siebie unikalne na całą aplikację)
 - logarytmiczny czas znajdowania węzła w zbiorniku (przy stałym czasie w
   przypadku std::list)

> a jak nie masz kluczy to zbiór (set).

Zbiór akurat składa się z samych kluczy i jest uogólnieniem słownika (mapy).

> >>>>>>>Wieź mi tu nie zalatuj przykładami kodu powstałymi w czasie kiedy Python był
> >>>>>>>co najwyżej w umyśle GvR.
> >>>>>
> >>>>>>Języki bezpieczne znane są od ponad 45 lat. Języki w których nie ma 
> >>>>>>podstawoych dziur w systemie typów były popularne już blisko 40 lat temu sic(!).
> >>>>>
> >>>>>A są nadal?
> >>>
> >>>>Ze dwa się ostały. Czasem pod smutowaną postacią, ale są.
> >>>
> >>>No więc czym przepraszam chcesz uzasadnić twierdzenia, jakoby bezpiecznych
> >>>języków ktokolwiek potrzebował?
> >>>
> >>>
> >>>
> >>>>>Powiedz, o które języki ci chodzi, to będziemy przynajmniej wiedzieli, na czym
> >>>>>stoimy.
> >>>
> >>>
> >>>>Pascal, Algol68, Lisp.
> >>>
> >>>
> >>>Pascal? Bezpieczny? Chyba jaja sobie robisz.
> > 
> >>Nie robię. Bezpieczna implementacja Pascala jest możliwa i jest naturalna. W 
> >>odróżnieniu od bezpiecznej implementacji C czy C++.
> > 
> > Jasne - po pozbawieniu Pascala np. wskaźników.

> Akurat wskaźniki nie przeszkadzają w bezpiecznej implementacji jeśli nie 
> masz na nich arytmetyki (a oryginalny Pascal AFAIR nie miał).

Czyżby? I masz udokumentowaną obsługę sytuacji wyjątkowej w przypadku
zerowego lub wiszącego wskaźnika?

> >>>>Co do przykładu -- na sieci pełno.
> >>>
> >>>To znajdź i wklej - dopóki tego nie zrobisz, dla mnie bredzisz od rzeczy.
> > 
> >>Nie jestem proxy do google. Oczywistości szukaj sobie sam.
> > 
> > Twoje oczywistości to dla mnie brednie - i obaj wiemy, że tylko ja mam z tego
> > ubaw.

> Ja tam mam niezły. Zwłaszcza gdy wymyślasz bzdury -- zrób sobie google 
> python container i nie ośmieszaj się.

Zrobiłem. Tylko jestem za leniwy, żeby ci wkleić te pierwsze 10 linków i
udowodnić, że nic nie ma na temat wspomnianego zbiornika.

> >>>>>Co nazywasz "resztą świata" - Javę, czy Lispa?
> >>>
> >>>>Javę, Smalltalka, skryptowce, itd...
> >>>
> >>>Javę, powiadasz? Tam, gdzie mapa nazywa się Map, a strumień Stream?
> >>
> >> >
> >>
> >>>Smalltalk to dla ciebie jest licząca się reszta świata?
> >>>Skryptowce, wśród których masz Tcl-a z Tablicą, Perla z Haszem i Pythona ze
> >>>Słownikiem?
> > 
> > 
> >>Masz jeszcze coś takiego jak ogólnie przyjętą nomenklaturę, reprezentowaną w 
> >>literaturze. Tu jest słownik lub tablica asocjacyjna, tablica dynamiczna itd.
> > 
> > I chcesz mi może tym stwierdzeniem uzasadnić, że istnieją jakieś "bardziej
> > ustandaryzowane" terminy obrazujące te pojęcia, skoro w powyższym zdaniu
> > użyłeś już różnych trzech?

> Fajsnie się topisz. Nie zauważyłeśm że trzecie z nich dotyczy czego innego 
> niż dwa piersze.

Aha, o tym, że niektórym zdarzało się nazywać słownik również tablicą
dynamiczną, również nie słyszałeś?

> >>Dałoby się, gdyby całość zaprojektowano a nie zrodzono z chaosu. Jak są 
> >>idiotyzmy w stylu vector<bool> to być może nie bardzo da się inaczej, by to 
> >>jeszcze było używalne jakkolwiek.
> > 
> > A co złego jest w vector<bool>?

> To, że nie jest kontenerem booli tylko pewnego śmiesznego typu 
> vector<bool>::reference?

I co w tym złego?

> Ze wszystkimi tego konsekwencjami dla rzeczy takich jak non-const 
> operator[], itd...

Jakimi znów konsekwencjami? Że trzeba się posłużyć typem pomocniczym? Że w
ogóle da się go zrobić?

> >>>>>a SFiNaE było od samego
> >>>>>początku podstawą funkcjonowania szablonów w C++.
> >>>
> >>>>I wszelakich tricków na nich opartych. Ale od początku to toto nie było. 
> >>>>Zobacz takie MSVC 5.0 -- tu np. nie działało.
> >>>
> >>>Oczywiście, że działało (jeśli oczywiście mówimy o M$VC 5.0 + SP2, które
> >>>obsługiwało np. przestrzenie nazw).
> > 
> >>Oczywiście, że nie działało. Namespejsy do nie świniae.
> > 
> > 
> > Ja wiem, bo używaliśmy tego w Aldecu, a jeszcze ZANIM tam przyszedłem (w
> > morde, to ok. 10 lat temu :), Wojtek Surówka tu na tej grupie udowadniał
> > Andrzejowi Lewandowskiemu, wykorzystując właśnie świniae, że wzorce nie dają
> > się żadną miarą porównać do makrogeneratora. Kod, który zacytował, nie działał
> > mi na ówczesnej wersji gcc (bo w tej wersji gcc świniae jeszcze nie działało),
> > więc domniemam, że został sprawdzony właśnie na VC5.
> > 

> Ja pamiętam jaja z MSVC i z tym, że jak jakaś, nawet nieużywana, metoda 
> szablonu oczekiwała czegoś od parametyzującego typu to to w tym typie 
> musiało istnieć. To jest zaprzeczenie SFINAE.

Ale czy to na pewno było VC5 + SP2?

(pomijając już to, że VC5 było i tak wciąż mocno w tyle za standardem, a nawet
z VC6 nie było lepiej - ale w wielu aspektach).

> >>>>>Można oczywiście kwestionować sensowność "ograniczania przez użycie" oraz
> >>>>>sensowność sposobu pracy komitetu, który wysysa sobie z palca reguły języka,
> >>>>>do których potem producenci kompilatorów muszą wyharatać implementacje (bo
> >>>>>jakby goście wcześniej zauważyli te spaghetti-messages, to może losy wzorców
> >>>>>potoczyłyby się inaczej). Ale na ówczesny stan wiedzy rozwiązanie wydawało się
> >>>>>najlepsze.
> >>>
> >>>>Wydawało? Czy się raczej wyłoniło się z chaosu (poprzedzających implementacji).
> >>>
> >>>Z tego, co BS napisał w "DAEC++", rozważano wiele możliwości, jeśli chodzi o
> >>>sprawdzanie dopasowania wzorców. Okazało się, że takie będzie najmniej
> >>>kłopotliwe.
> > 
> >>W zastanej sytuacji chaosu istniejących implementacji.
> > 
> > 
> > Nie było jeszcze żadnych implementacji, kiedy to rozważano. Nie mogło być, bo
> > omawiano tam całkiem podstawowe kwestie (takie jak np. czy używać template
> > <class T> class X, czy class X<T>, jak w Javie jest to teraz), których nawet
> > nie można by poddać pod rozważanie, gdyby jakiekolwiek implementacje już
> > istniały.

> Sorry, Sektor, Ale Koenig lookup to jest rzecz dużo późniejsza, na tyle 
> późniejsza, że dopiero teraz kompilatory to poprawnie implementują.

Ale nie SFINAE.

> >>>>>Właśnie ostatnio się o tym przekonałem. Java, jako jedyny język z grupy
> >>>>>Java/C#/C++, posiada ścisłe wyjątki.
> >>>>
> >>>>[...]
> >>>>
> >>>>
> >>>>>I to jest ficzer, który mocno utrudnia życie, nie sądzę żeby przyczyniał się
> >>>>>do zwiększenia jakości developmentu, a zmienić go już nie będzie można. A do
> >>>>>wzorców w C++ definiowanie ograniczeń dodać można.
> >>>>>
> >>>>>I która z tych pomyłek jest bardziej spektakularna?
> >>>
> >>>
> >>>>Ze specyfikacjami wyjąytków to jest tak, że zwalono je zarówno w C++ jak i w 
> >>>>Javie, przy czym statyka Javowa lepiej pasuje do C++ a dynamika z C++ do Javy.
> >>>
> >>>Wyjątki są dynamiczne, czy tego chcesz, czy nie.
> > 
> >>Ale ich specyfikacje mogą być mniej lub bardziej dynamiczne.
> > 
> > Niespecjalnie. Chyba że mówimy o statycznej weryfikacji wyjątków, ale to w
> > semantyce wyjątków niczego nie zmienia.

> Właśnie od tego są specyfikacje wyjątków. Tez z C++ są dynamicznie 
> kontrolowane a te z Javy statycznie. W obu przypadkach wbrwe charakterom 
> języków.

Ale statyczna kontrola nie zmienia dynamicznego charakteru wyjątków. Ani też
Java nie jest na tyle bardziej dynamiczna od C++, żeby to robiło jakąkolwiek
różnicę (statyczna kontrola wyjątków jest na poziomie typów, jak i podobnie
jest w C++ ze statyczną kontrolą).

> >>>mieć do nich statyczne wsparcie, bo trzeba sobie zdawać sprawę z tego, że
> >>>wszelkie statyczne wsparcie to potencjalne utrudnienia dla użytkownika.
> >>>
> >>>Poza tym, Java nie jest wcale taka znów dynamiczna. Nie widzę w tym względzie
> >>>żadnych większych różnic od C++.
> > 
> >>C++ (zwłaszcza modern) dużą większy nacisk kłądzie na statyzm.
> > 
> > Z powodu wzorców?

> Głównie z powodu przyjętych obyczajów (STL vs Smalltalk-like hierarchy). A 
> także z braku paru dynamicznych mechanizmów (choćby refleksja, ładowanie 
> dynamiczne klas, itp).

Nie. Słabo znasz historię C++. Początkowo do C++ miały być stworzone właśnie
takie kolekcje, z taką właśnie hierarchią, jak to jest w Javie. Zrezygnowano z
tego w imię wydajności. Zbiorniki robione obiektowo, z hierarchią,
wprowadziłyby wiele blokad w optymalizacji. Podejrzewam, że gdyby strumienie
standardowe postały później, też by je to czekało.

> >>A specyfikacje wyjątków są nie z tego ni z owego sprawdzane dynamicznie.
> > 
> > Nie "ni z tego ni z owego", tylko dlatego, że inaczej nie jest to możliwe do
> > wykonania.

> To jakim cudem to działą w Dżawie??? Sektor, nie wypisuj głupot.

Utrudniając życie użytkownikowi i zmuszając go niekiedy do "przemycania"
wyjątków (czyli dobrowolnej rezygnacji z jakiegokolwiek sprawdzania)?

Dziękuję, postoję.

W Javie nie da się nawet SKRÓCIĆ listy tych wyjątków - czyli wypuszczać np.
tylko NullPointerException.

> >>Za to Java w której jest istotny odsetek elementów dynamicznych ma nagle
> >>statyczną kontrolę wyjątków.
> > 
> > Poza statyczną kontrolą - która do samego działania wyjątków niczego nie wnosi
> > - nie ma tam nic statycznego.

> Statyczność jeżyka to jest właśnie statyczna kontrola! Obliczenia zawsze są 
> dynamiczne, nawet w Sparku.

Jakie obliczenia i jaką kontrolę masz tu na myśli?

> >>Jakby było odwrotnie to byłoby lepiej, co nie znaczy że byłoby dobrze :)
> > 
> > Nie widzę związku - jakby C++ miał statyczną kontrolę wyjątków, to ludzie
> > nienawidziliby go jeszcze bardziej :). Natomiast brak ten kontroli mógłby
> > pomóc Javie, ale to nie ma znaczenia, skoro programiści i tak Javę kochają.

> Akurat statyczna kontrola wyjątków by wiele nei zmieniła. Wyjechałoby 
> unexpected. Bo to że teraz można zrobić:

> void foo() throws();
> {
>    throw bar;
> }

> jest wyraźną niekonsekwencją języka.

Tu się zgadzam, że kompilator mógłby przynajmniej postarać się o ostrzeżenie
(ale ponieważ wszystkie autorytety dzisiaj zgodnie olewają specyfikację
wyjątków w C++, to i wartość biznesowa tego ficzera jest zbyt niska).

Jedynym sensownym sposobem na statyczne sprawdzanie wyjątków byłby analizator
kodu, który sam sprawdza, jakie wyjątki są rzucane przez jakie funkcje. I
dodatkowo, żeby produkował z tego raport, na bazie którego kompilator mógłby
dokonać optymalizacji.

Wymuszanie specyfikacji wyjątków przez kompilator skutkuje bowiem stosowaniem
praktyki "przemycania" wyjątków.

> W Javie byłoby to bardziej na mijescu niż w C++.

Moim zdaniem jest tak samo na miejscu w Javie, jak i C++; co najwyżej zgodzę
się, że zniesienie statycznej kontroli wyjątków w Javie przyniosłoby więcej
pozytywnych skutków, niż podobna operacja w C++ (gdyby w C++ istniała ścisła
kontrola wyjątków). Przykładowo, można by było rzucić wyjątkiem klasy nie
znanej w momencie kompilacji.

> > Kwestia statycznej kontroli wyjątków nie ma akurat żadnego znaczenia dla
> > statyzmu wyjątków, skoro ich działanie jest typowo dynamiczne tak czy siak.

> Wszelkie obliczenia s a dynamiczne tak czy siak. Co nie znaczy że typy na 
> których są oparte są dynamiczne.

No przecież typy wyjątków w C++ są statyczne, więc o co chodzi?

> >>>Cóż, trudno mi się nie zgodzić :)
> >>>
> >>>Ale linuxowe implementacje akurat takich problemów nie mają (na szczęście, bo
> >>>inaczej to nie wiem, gdzie bym tą aplikację uruchomił!).
> > 
> >>Linuksowe jak najbardziej mają sporo problemów. Zwłaszcza jak gdzieś jeszcze 
> >>uchował się system sprzed NPTL.
> > 
> > Nie zauważyłem.

> Pobaw się trochę z sygnałami na systemie bez NPTL a poitem z NPTL :)

> Albo choćby taki "szczegół" jak get_pid() :)

Ano to ja wiem, że implementacja LinuxThreads jest niezgodna z POSIX. Ale
szczęściem nie mam dziś nigdzie w użyciu systemu z jądrem sprzed 2.6.

> >>>>Ani o tym ani o tym. Chodzi o to, by błędy wykonania były "contained". Niech 
> >>>>sobie będzie abort, wyjątek, cokolwiek, ale niech po pierwsze będzie a po 
> >>>>drugie niech będzie tylko to (a nie losowa poprawka do przetwarzanych danych).
> >>>
> >>>Dobrze, nawet się zgadzam. To teraz przystaw to do praktycznych możliwości
> >>>realizacji powyższych założeń.
> >>>
> >>>Jeśli chodzi np. o odwołanie się do zerowego wskaźnika, to masz tu dwie
> >>>możliwości: albo w języku sprawdzasz wskaźnik przed każdym odwołaniem
> >>>(usuwając jedynie zbędne sprawdzenia, gdy jest to bezużyteczne), albo
> >>>posiadasz platformę wirtualną, na której uruchamiany jest program, i która to
> >>>platforma sama posiada odpowiednie właściwości pozwalające na wygenerowanie
> >>>wyjątku w takim przypadku. W obu przypadkach mamy do czynienia z dodatkowym
> >>>narzutem, który jest tylko czasem akceptowalny.
> > 
> >>W większości systemów nie embedded masz tą wirtualizację daną z góry i nie 
> >>masz wyboru.
> > 
> > Ale to się do niczego nie nadaje.

> Co się nie nadaje? To się zachowuje całkowicie deterministrycznie. Zarówno 
> na windowsach, gdzie jest SEH jak i nauniksach, gdzie masz sygnały moża 
> rzecz załatwić na poziomie runtime języka.

Rzecz w tym, że to nie takie proste.

Nie każdy system posiada systemową implementację takiej np. malloc. Czy dziś
jakieś systemy nie mają - tego nie wiem, ale w którymś ze starszych
posixowych systemów funkcja malloc była normalną funkcją użytkownika i sama
zarządzała zasobami, w kwestii systemu poprzestając jedynie na sbrk(). Co
oznacza np., że aplikacja nigdy nie oddawała do systemu przydzielonej pamięci,
a także przydzielała przez sbrk() większe bloki i wydzielała kawałki tortu z
jej środka. W takim przypadku niemożliwe jest określenie, czy odwołanie do
określonego miejsca w pamięci odwołuje się do przydzielonego kawałka, czy nie.

Anyway, nie wiem, czy nie wystarczyłoby coś w rodzaju platformy w podobnym
stylu, co robi C#. W sensie, że niby masz ograniczenia platformy, ale i tak
program wykonuje się na platformie natywnej.

> >>>Wątki po prostu powinny pracować na niezależnych danych.
> > 
> >>Wtedy mogą być równie dobrze procesami. Tzn. niech mają osobną przestrzeń 
> >>adresową i już.
> > 
> > 
> > Gdyby na ZUPEŁNIE niezależnych danych pracowały, to wtedy tak, co więcej,
> > takie procesy nawet nie wymagają komunikacji.
> > 
> > Ale - jak to napisałem gdzieś - jest to sytuacja idealna, której na dodatek
> > nikt nie zamierza osiągać. Im mniej danych wątki wymieniają między sobą, tym
> > lepiej, ale jeśli nie wymieniałyby ich w ogóle, to istnienie wątków traci
> > sens.
> > 
> > Chodzi więc o to, że w przypadku wątków dane przekazuje się znacznie wygodniej
> > i wątki mogą raz na jakiś czas korzystać z tych danych. Nie powinny jednak na
> > nich "pracować" to znaczy odwoływać się do wspólnych danych przez cały czas
> > swojej pracy.

> Akurat można sobie zogranizować komunikację między procesami też żeby była 
> zupełnie wygodna.

I tworzyć np. obiekty w dzielonej pamięci? Nie bardzo mi się to widzi.

Nie bez powodu stworzono normalny mechanizm wątków - gdyby komunikacja
międzyprocesowa wystarczała, nikt by tego nie tworzył.

> >>[...]
> >>
> >>>Mało co prawda napisałem w życiu aplikacji z użyciem wątków, ale jak na razie
> >>>zawsze obchodziłem się bez muteksów. Używałem jedynie volatile.
> > 
> >>Rozumiem, że chodzi o volatile z Dżawy, nie to cóś z C/C++.
> > 
> > Ależ oczywiście, że chodzi o oba. Zresztą znaczenie 'volatile' w Javie i w C++
> > jest identyczne\

> Ależ skąd!

> > (jeśli oczywiście uwzględnimy fakt, że gcc ma rozszerzenie w
> > stosunku do standardu, co pozwala zmiennym oznaczonym volatile pracować
> > poprawnie z posix threads).

> Chyba coś zmyślasz... Volatile które ma semantykę acquire/release? W GCC??? 
> Takie volatile to jest sobie w MSVC z VS.NET 2005, ale nie w GCC.

To zależy.

> A w standardzie C++ volatile dotyczy tylko i wyłącznie sygnałów i nic 
> więcej. O wątkach nie ma mowy bo takie pojęcie w C++ nie występuje

To się akurat zgadza.

-- 
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Technical Details
Message-ID: <fjmo4o$a5r$1@kujawiak.man.lodz.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!newsfeed.silweb.pl!news.man.lodz.pl!not-for-mail
References: <fghgeo$spf$1@nemesis.news.tpi.pl> <fghsb4$kpq$1@news.dialog.net.pl> <fgo4c7$mtu$1@news.vectranet.pl> <20071106073039.433f4934@Vorago> <fgqn9m$74j$2@news.vectranet.pl> <618565031.20071107113041@pkierski.net> <fgt6sh$jov$1@news.vectranet.pl> <fgtb6j$nur$1@news.vectranet.pl> <fgv6ba$k14$1@bozon2.softax.pl> <fgvkne$u3b$1@news.vectranet.pl> <fh1tjd$dtt$1@bozon2.softax.pl> <fh2lj6$qkh$1@news.vectranet.pl> <fha3as$pap$1@bozon2.softax.pl> <fhaj8u$e02$1@news.vectranet.pl> <fhf09d$ohq$1@bozon2.softax.pl> <fhfi9l$640$1@news.vectranet.pl> <fhurmu$5d9$1@bozon2.softax.pl> <fhv020$8k1$1@news.vectranet.pl> <fi1bs4$nn3$1@bozon2.softax.pl> <fi27ds$gt1$1@kujawiak.man.lodz.pl> <fi458p$fmv$1@bozon2.softax.pl> <fi9ckc$2u5$1@kujawiak.man.lodz.pl> <fimb7n$80v$1@bozon2.softax.pl> <fj5k6j$r3e$1@kujawiak.man.lodz.pl> <fj68ei$vbo$1@bozon2.softax.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!newsfeed.silweb.pl!news.man.lodz.pl!not-for-mail
From: Sektor van Skijlen <ethouris@guess.if.gmail.com.is.valid.or.invalid>
Newsgroups: pl.comp.lang.c
Subject: Re: Ciemna strona C++
Date: Tue, 11 Dec 2007 19:24:08 +0000 (UTC)
Organization: LODMAN - Metropolitan Area Network in LODZ, Poland
Lines: 707
Sender: Michal Malecki <sektor@student.kis.p.lodz.pl>
Message-ID: <fjmo4o$a5r$1@kujawiak.man.lodz.pl>
References: <fghgeo$spf$1@nemesis.news.tpi.pl> <fghsb4$kpq$1@news.dialog.net.pl> <fgo4c7$mtu$1@news.vectranet.pl> <20071106073039.433f4934@Vorago> <fgqn9m$74j$2@news.vectranet.pl> <618565031.20071107113041@pkierski.net> <fgt6sh$jov$1@news.vectranet.pl> <fgtb6j$nur$1@news.vectranet.pl> <fgv6ba$k14$1@bozon2.softax.pl> <fgvkne$u3b$1@news.vectranet.pl> <fh1tjd$dtt$1@bozon2.softax.pl> <fh2lj6$qkh$1@news.vectranet.pl> <fha3as$pap$1@bozon2.softax.pl> <fhaj8u$e02$1@news.vectranet.pl> <fhf09d$ohq$1@bozon2.softax.pl> <fhfi9l$640$1@news.vectranet.pl> <fhurmu$5d9$1@bozon2.softax.pl> <fhv020$8k1$1@news.vectranet.pl> <fi1bs4$nn3$1@bozon2.softax.pl> <fi27ds$gt1$1@kujawiak.man.lodz.pl> <fi458p$fmv$1@bozon2.softax.pl> <fi9ckc$2u5$1@kujawiak.man.lodz.pl> <fimb7n$80v$1@bozon2.softax.pl> <fj5k6j$r3e$1@kujawiak.man.lodz.pl> <fj68ei$vbo$1@bozon2.softax.pl>
NNTP-Posting-Host: student.kis.p.lodz.pl
Mime-Version: 1.0
X-Trace: kujawiak.man.lodz.pl 1197401048 10427 212.191.89.21 (11 Dec 2007 19:24:08 GMT)
X-Complaints-To: abuse@man.lodz.pl
NNTP-Posting-Date: Tue, 11 Dec 2007 19:24:08 +0000 (UTC)
User-Agent: tin/1.8.3-20070201 ("Scotasay") (UNIX) (FreeBSD/6.2-RELEASE-p3 (sparc64))
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit