Co jest nie tak z cplusplus.com?


200

To może nie jest idealnie odpowiednie forum na to pytanie, ale pozwólcie, że spróbuję, ryzykując odejście.

Istnieje kilka odniesień do standardowej biblioteki C ++, w tym nieoceniony standard ISO, MSDN , IBM , cppreference i cplusplus . Osobiście, kiedy piszę C ++, potrzebuję referencji, która ma szybki dostęp losowy, krótkie czasy ładowania i przykłady użycia, a cplusplus.com uważam za bardzo użyteczny. Jednak często słyszę negatywne opinie na temat tej witryny tutaj, na SO, więc chciałbym uzyskać konkretne:

Jakie są błędy, nieporozumienia lub złe porady udzielone przez cplusplus.com? Jakie ryzyko wiąże się z użyciem go do podejmowania decyzji dotyczących kodowania?

Pozwólcie, że dodam ten punkt: chcę móc odpowiedzieć na pytania tutaj na SO z dokładnymi cytatami standardu, dlatego chciałbym zamieścić linki, które można natychmiast wykorzystać, a cplusplus.com byłaby moją ulubioną witryną, gdyby nie ten przypadek.


62
Dlaczego opinie negatywne? To jest całkowicie poprawne pytanie. Jeśli potrzebujesz referencji, potrzebujesz zaufanego źródła. Słyszałem także skargi na cplusplus.com, gdzie mogę uzyskać szybki przegląd standardowej biblioteki i jako taki jest interesujący.
Xeo

48
@Olafur: Nie chcę opinii, chcę konkretnych list błędów na tej stronie. Jeśli nie ma, chcę móc użyć tego pytania, aby rozwiać przyszłą krytykę.
Kerrek SB,

4
@ Ólafur Waage: może. Można jednak postawić całkowicie obiektywne uwagi na temat dokładności / prawdziwości treści tej witryny.
Daniel Sloof

14
Jesteśmy już na pierwszej stronie „cplusplus.com” w Google. To imponujące, jak szybko pytania SO wspinają się w rankingach wyszukiwania.
Wyścigi lekkości na orbicie

5
Myślę, że to sprawiedliwe - biorąc pod uwagę, jak wysoko to pytanie zajmuje pozycję przy wyszukiwaniu hasła „cplusplus” - należy zauważyć, że odkąd zadano to pytanie, na stronie cplusplus.com wprowadzono szereg poprawek. W rzeczywistości trzy najlepsze odpowiedzi wskazujące na błędy nie są już prawdziwe.
Mark H

Odpowiedzi:


72

Edycja: Dokumentacja dla std::removezostała naprawiona od czasu napisania tej odpowiedzi. To samo dotyczy list::remove.

Pozwól, że podam przykład pokazujący, jak cpluscplus.com może to zrobić źle.

Rozważ std::removefunkcję od <algorithm>.

Faktem jest, że std::removenie usuwa przedmiotu z pojemnika. Jest tak, ponieważ std::removedziała tylko z parą iteratorów i nie wie nic o kontenerze, który faktycznie zawiera elementy. W rzeczywistości nie jest możliwe std::removepoznanie podstawowego kontenera, ponieważ nie ma możliwości, aby para iteratorów odkryła kontener, do którego należą iteratory. Więc std::removetak naprawdę nie usuwa przedmiotów, po prostu dlatego, że nie może . Jedynym sposobem na faktyczne usunięcie elementu z kontenera jest wywołanie funkcji członka na tym kontenerze.

Więc jeśli chcesz usunąć elementy, użyj Erase-Remove Idiom :

 v.erase(std::remove(v.begin(), v.end(), 10), v.end()); 

Ale cplusplus.compodaje nieprawidłowe informacje na temat std::remove. To mówi

Zauważ, że ta funkcja nie zmienia elementów za nowym końcem, które zachowują swoje stare wartości i są nadal dostępne .

co nie jest poprawne. Iterator w zakresie [new_end, old_end)jest nadal dereferencyjny, ale to wcale nie znaczy, że zachowują stare wartości i są nadal dostępne. Są nieokreślone.


Podobnie cplusplus.compodaje również nieprawidłowe informacje na temat list::remove. Mówi :

Zauważ, że globalna funkcja algorytmu, remove, istnieje z podobnym zachowaniem, ale działa między dwoma iteratorami.

co jest całkowicie błędne. Globalne usunięcie mianowicie std::removenie jest podobne list::remove, jak widzieliśmy, że ten pierwszy NIE usuwa rzeczy z kontenera, ponieważ nie może , podczas gdy drugi (funkcja członka) naprawdę usuwa elementy, ponieważ może .

Ta odpowiedź została skopiowana z mojej innej odpowiedzi w następującym temacie, z niewielkimi modyfikacjami:

Uwaga: odkąd ostatnio na to natrafiłem, odpowiadając na powyższy temat, pamiętam to. W ciągu ostatnich dwóch lat napotkałem wiele błędów, których nie pamiętam. Mogę dodać kilka później, jeśli znów się spotkam.


1
+1: czy na stronie jest o wiele więcej tych nieprawidłowych stwierdzeń?
Klaim

4
@Alexander: list::removeusuwa elementy z pojemnika. Ale std::removeNIE usuwa elementów z pojemnika. Nie mogę powiedzieć, że ich zachowanie jest „podobne”.
Nawaz

3
Dobry chwyt! To bardzo dobry przykład rzeczy, których szukam.
Kerrek SB,

3
„Podobny” jest dyskusyjny, ponieważ zależy od tego, czy dwie różne operacje są podobne, czy nie. Można również dyskutować, czy cplusplus.com powinien oferować opinię pod przykrywką dokumentacji. Ale w każdym razie „zachowaj swoje stare wartości” jest niewybaczalnym błędem, po prostu pokazuje, że opis cplusplus nie był oparty na standardzie.
Steve Jessop

5
@ Steve: Powiedziałeś "Similar" is debateable. Jeśli słowo similarjest dyskusyjne, to bardzo mówi, że to słowo nie jest poprawnym słowem i należy go unikać, wyjaśniając zachowanie, std::removea list::removeponieważ wyjaśnienie powinno być jak najbardziej jasne, nie powinno wymagać innego wyjaśnienia.
Nawaz

38

Mam zamiar zaoferować opinię nieco przeciwną. Istnieje wiele dobrych informacji na cplusplus.com. Wybierz to na śmierć i tak, oczywiście, że ma swoje problemy, ale która strona nie? Na pewno nie ta strona . Ludzie mieszkający w szklanych domach nie powinni rzucać kamieniami. Jest tu również wiele dezinformacji. Są akceptowane odpowiedzi, które są całkowicie błędne, odrzucone (niektóre negatywne!), Które są trafne.

Jednym z problemów z cplusplus.com jest to, że jest to zamknięta strona; to samo dotyczy większości innych wspomnianych witryn referencyjnych. Jest to sprzeczne z założeniami witryny opracowanej przez społeczność, takiej jak Przepełnienie stosu. Zdobycie możliwości dokonywania zaufanych edycji nie trwa tak długo, a nawet nowi nowicjusze mogą łatwo zaproponować ulepszenia. Porównaj to z cplusplus.com. Jesteś wiecznym nowicjuszem, jeśli nie jesteś w ich personelu. Nawet jeśli jesteś kluczowym członkiem WG21, musisz przejrzeć ich mechanizm zgłaszania wiadomości e-mail, jeśli zauważysz błąd gdzieś na tej stronie. Anatema!

Na tej stronie byłoby dla nas rozwiązaniem opracowanie własnego odniesienia do C ++. Zajmie to sporo pracy. Musielibyśmy uważać, aby nie być zbyt pedantycznym / zbyt technicznym; oczywiste jest, że cplusplus.com zatrudnia co najmniej kilku redaktorów technicznych, którzy trzymają pedały na dystans. Musielibyśmy dobrze zorganizować informacje; FAQ tutaj nie są dobrze zorganizowane. Musielibyśmy również bardzo uważać, aby nie wyrzucać zbyt wiele bezpośrednio ze standardu; to nielegalne.


7
Kiedyś często odwiedzałem stary cppreference.com, ale teraz przerobili go na coś wiki (czy każdy może go edytować?) ... i tak naprawdę już go nie lubię. Uważam, że trudno jest zobaczyć ważną informację. Po prostu brakuje mu natychmiastowej gratyfikacji, którą otrzymuję z cplusplus.com. Myślę.
Kerrek SB,

14
Zaraz! Widzę dokładne przeciwieństwo. Przestałem często odwiedzać stary cppreference.com, ponieważ trudno mi było przejść i źle napisać. Nowa strona cppreference.com wydaje się być pozbawioną reklam witryną opartą na społeczności, która robi dokładnie to, co zasugerowałem w poprzednim akapicie.
David Hammen

1
Może to tylko ja, spróbuję jeszcze raz. Myślę, że chciałem poszukać czegoś <thread>lub czegoś <atomic>takiego i po prostu dostałem „proszę napisz tę stronę”, więc się poddałem. Pozwól, że sprawdzę jeszcze raz! Och, obsługa C ++ 0x byłaby oczywiście ogromną zaletą!
Kerrek SB,

10
„Ludzie mieszkający w szklanych domach nie powinni rzucać kamieniami”. SO nie twierdzi (częściowo), że jest odwołaniem do biblioteki dla C ++, jak to robi cplusplus.com/reference . Kiedy ludzie zgłaszają tutaj roszczenia, powołują się na standard, aby je poprzeć, a jeśli nie, to przychodzi ktoś inny i wypełnia formularz. Jeśli się mylą, możesz zobaczyć, jak działają. Jeśli cplusplus.com jest błędny, właśnie napisałeś kod, który zawiedzie w niektórych implementacjach C ++ innych niż ten, którego autor użył do stworzenia „szczegółowego opisu jego elementów”. Problem polega na tym, że cplusplus.com jest nieformalny, ale napisany, aby wyglądać na formalny.
Steve Jessop

4
SO jest nieformalny i napisany, aby wyglądać nieformalnie. Teraz, jeśli cplusplus.com nie ma być dokładną dokumentacją / materiałem referencyjnym i przegapiłem gdzieś zastrzeżenie, to dość uczciwe, załóżmy, że rzucisz kamieniami w ludzi, którzy z niego korzystają w ten sposób, a nie w samą stronę. Chodzi o to, że tylko dlatego, że cplusplus.com mówi coś o funkcji C ++, nie oznacza, że ​​to prawda, i warto wiedzieć, że jeśli planujesz użyć jej jako szybkiego odniesienia. Używam go do wyszukiwania podpisów funkcji, ale nigdy nie ustalam, czy mój kod jest zgodny, czy nie.
Steve Jessop

14

http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

Nie wspomina, że ​​„Jeśli kopiowanie odbywa się między nakładającymi się obiektami, zachowanie jest niezdefiniowane”. (4.11.2.4 w standardzie C89. Nie mam kopii C90, do czego tak naprawdę odnosi się C ++ 03, ale powinny się one różnić tylko takimi elementami, jak numeracja stron.)


Ach, stara biblioteka C ... miło.
Kerrek SB,

6
Oni wspominają destination and source shall not overlap.
Sniper

2
@Sniper „nie nakłada się” to nie to samo, co „zachowanie jest niezdefiniowane”. Twój komentarz faktycznie uwidacznia jedną z subtelnych, wszechobecnych wad cplusplus.com - brzmi dobrze, ale nie jest poprawny.
Andrew Henle,

@Sniper: Myślę, że prawdopodobnie nie powiedziałem, że kiedy udzieliłem tej odpowiedzi w 2011 r., Uznałbym, że „nie będą się nakładać” jako wystarczające ograniczenie nakładów.
Steve Jessop

9

Dokumentacja podana przez cplusplus.com jest często niepoprawna lub niekompletna.

Takim przykładem jest atoidokumentacja na cplusplus.com.

atoi
W sekcji Return nie ma wzmianki o wartości zwracanej 0, jeśli nie można wykonać konwersji podczas używania funkcji.

cplusplus.com Zwrot w sekcji brzmi „... Jeśli przekonwertowana wartość byłaby poza zakresem reprezentowalnych wartości przez int, powoduje to niezdefiniowane zachowanie”.

Jest to poprawne, zgodnie ze standardowym „ Jeśli wartości liczbowej ciągu nie można przedstawić w int, zachowanie jest niezdefiniowane ”.

Jednak sekcja nie jest pełna, ponieważ nie podaje 0 jako wartości zwracanej, co może wprowadzać w błąd. Wyrażenie „... konwersja nie jest wykonywana, a zwracane jest zero”. jest spełniony wcześniej w akapicie opisu, ale konieczne jest, aby mieć go w sekcji Zwrot .

Wiele przykładowych kodów źródłowych podanych na stronie cplusplus.com jest niepoprawnych.
Wielu początkujących, którzy szukają tych referencji, popełniają poważne błędy.

Aby zacytować przykład:

EDYCJA: Przywołany wcześniej przykład był niepoprawny.


5
Być może ballant -> rażący? Ballant to jednak francuskie słowo określające „zwisające”, które może być trafne w przypadku błędów związanych ze wskaźnikami.
hardmath

Przeczytaj ponownie przykład iteratora ... nie ma niezdefiniowanego zachowania.
Dennis Zickefoose

1
Zadeklarowałeś „Wiele przykładowych kodów źródłowych podanych na stronie cplusplus.com jest niepoprawnych”. a następnie usunąłem przykład z napisem „Przykład, który poprzednio cytowałem, był niepoprawny”. - Dlaczego zatem usunąłeś przykład? :)
user2962533

Według tej witryny opisany przypadek powoduje niezdefiniowane zachowanie, a nie niezdefiniowane zachowanie. en.cppreference.com/w/cpp/string/byte/atoi ; Wygląda jednak na to, że Cplusplus.com zaktualizował swoją dokumentację, aby pasowała do tego, co mówisz. Najwyraźniej odpowiadają na prośby społeczności o poprawki. Niemniej jednak nie jestem pewien, która strona jest najbardziej poprawna, ponieważ te dwa pytania opisują bardzo różne rzeczy.
shawn1874,

Minęło 9 lat od opublikowania tej odpowiedzi. Czy nadal ogólnie uważa się, że Cplusplus.com zawiera znaczną liczbę nieprawidłowych lub niekompletnych informacji?
Tyler Shellberg,

3

Dokumentacja dotycząca type_infoprób wyjaśnienia typeidnajpierw, ale kończy się niepowodzeniem:

typeid można zastosować bezpośrednio do typów, w którym to przypadku zwraca informacje; Lub do obiektów, w którym to przypadku zwraca informacje o typie obiektu.

Gdy typeid jest stosowany do dereferencyjnego wskaźnika do obiektu typu polimorficznego (klasa deklarująca lub dziedzicząca funkcję wirtualną), bierze pod uwagę jego typ dynamiczny (tj. Typ obiektu najbardziej pochodnego).

Teraz drugi akapit już się nie zgadza z pierwszym. W typeid(*ptr), typeidjest stosowane do ekspresji. Jest to dość istotne, ponieważ pojęcie statici dynamictypy mają sens tylko w kontekście ekspresji, a nie przedmiotów. Pomija także przypadki takie jak typeid(foo()).

Ponadto akapit drugi pomija odniesienia. One także mogą mieć typy statyczne różne od typu dynamicznego obiektu, do którego się odnoszą.


Bardzo fajnie - pytania RTTI pojawiają się na SO z przewidywalną regularnością. Dobrze wiedzieć, czego nie powołać.
Kerrek SB,

3

Dokumentacja std::pair<T1,T2>::operator==mówi, że oba elementy są testowane pod kątem równości. Dokumentacja std::pair<T1,T2>::operator<mówi, że drugie elementy są brane pod uwagę tylko wtedy, gdy pierwsze elementy są równe.

Słowo „równy” pojawia się w obu przypadkach. Jednak tylko w pierwszym przypadku to naprawdę oznacza T::operator==. W drugim przypadku równe środki!(a.first<b.first || b.first<a.first)


Czy jest to obowiązkowe, czy biblioteka może swobodnie korzystać operator==w drugim przypadku, jeśli operator jest dostępny?
Kerrek SB,

1
Obowiązkowy. Standard C ++ nie łączy operator==i operator<.
MSalters
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.