O que há de errado com cplusplus.com?

201

Talvez esse não seja um fórum perfeitamente adequado para essa pergunta, mas deixe-me tentar, com o risco de ser afastado.

Existem várias referências para a biblioteca padrão C ++, incluindo o inestimável padrão ISO, MSDN , IBM , cppreference e cplusplus . Pessoalmente, ao escrever C ++, preciso de uma referência que tenha acesso aleatório rápido, tempos de carregamento curtos e exemplos de uso, e tenho achado o cplusplus.com bastante útil. No entanto, tenho ouvido opiniões negativas sobre esse site frequentemente aqui no SO, então gostaria de ser mais específico:

Quais são os erros, conceitos errados ou conselhos ruins dados pelo cplusplus.com? Quais são os riscos de usá-lo para tomar decisões de codificação?

Deixe-me acrescentar este ponto: quero poder responder perguntas aqui no SO com aspas precisas do padrão e, portanto, gostaria de postar links imediatamente utilizáveis, e cplusplus.com teria sido o meu site preferido se não fosse por esse assunto.

Kerrek SB
fonte
62
Por que os votos negativos? Esta é uma pergunta perfeitamente válida. Se você precisar de uma referência, deseja uma fonte confiável. Também ouvi reclamações contra o cplusplus.com, onde posso obter uma referência rápida para a biblioteca padrão e, como tal, isso é interessante.
Xeo 29/06
48
@Olafur: não quero opinião, quero listagens concretas de erros nesse site. Se não houver, quero poder usar esta pergunta para dissipar críticas futuras.
Kerrek SB 29/06/11
4
@ Ólafur Waage: talvez. Mas pontos perfeitamente objetivos podem ser feitos sobre a precisão / veracidade do conteúdo desse site.
Daniel Sloof
14
Já estamos na página um de "cplusplus.com" no Google. É impressionante a rapidez com que as perguntas de SO sobem no ranking de pesquisa.
Lightness Races in Orbit
5
Eu acho que é justo - considerando o grau em que essa pergunta está classificada nas pesquisas por "cplusplus" - observe que, desde que essa pergunta foi feita, várias correções foram feitas no cplusplus.com. De fato, as três principais respostas que apontam erros não são mais verdadeiras.
Mark H

Respostas:

72

Editar: a documentação para std::removefoi corrigida desde que esta resposta foi escrita. A mesma coisa se aplica a list::remove.

Deixe-me dar um exemplo para mostrar como o cpluscplus.com pode errar.

Considere a std::removefunção de <algorithm>.

O fato é que std::removenão remove o item do contêiner. É porque std::removefunciona apenas com um par de iteradores e não sabe nada sobre o contêiner que realmente contém os itens. De fato, não é possível std::removeconhecer o contêiner subjacente, porque não há como ir de um par de iteradores para descobrir sobre o contêiner ao qual os iteradores pertencem. Então std::remove, realmente não remove os itens, simplesmente porque não pode . A única maneira de realmente remover um item de um contêiner é invocar uma função de membro nesse contêiner.

Portanto, se você deseja remover os itens, use Erase-Remove Idiom :

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

Mas cplusplus.comfornece informações incorretas sobre std::remove. Diz

Observe que essa função não altera os elementos além do novo fim, que mantêm seus valores antigos e ainda estão acessíveis .

o que não está correto. O iterador no intervalo [new_end, old_end)ainda é desreferenciável, mas isso NÃO significa que eles mantêm os valores antigos e ainda estão acessíveis. Eles não são especificados.


Da mesma forma, também cplusplus.comfornece informações incorretaslist::remove . Ele diz ,

Observe que uma função de algoritmo global, remove, existe com um comportamento semelhante, mas operando entre dois iteradores.

o que está completamente errado. A remoção global, ou std::removeseja, não é semelhante a list::remove, como vimos que o antigo NÃO remove realmente os itens do contêiner porque não pode , enquanto o último (a função de membro) remove os itens porque pode .

Esta resposta é copiada da minha outra resposta no tópico a seguir, com poucas modificações:

Nota: Desde que me deparei com isso recentemente, quando estava respondendo no tópico acima, lembro-me dele. Existem muitos erros que encontrei nos últimos dois anos, dos quais não me lembro. Posso acrescentar mais alguns depois, se me deparar novamente.

Nawaz
fonte
1
+1: há muito mais dessas declarações incorretas neste site?
Klaim
4
@ Alexander: list::removeremove os elementos do contêiner. Mas std::removeNÃO remove os elementos do contêiner. Não posso dizer que o comportamento deles seja "semelhante".
Nawaz 29/06
3
Boa pegada! Esse é um bom exemplo das coisas que estou procurando.
Kerrek SB
3
"Similar" é discutível, pois é uma questão de opinião se duas operações diferentes são semelhantes ou não. Também é discutível se cplusplus.com deve oferecer opiniões disfarçadas de documentação. De qualquer forma, "manter os valores antigos" é um erro imperdoável, apenas mostra que a descrição do cplusplus não foi baseada no padrão.
21711 Steve Joplin
5
@ Steve: Você disse "Similar" is debateable. Se a palavra similaré discutível, ela diz muito que ela não é a palavra correta e deve ser evitada ao explicar o comportamento de std::removee list::remove, porque uma explicação deve ser clara o máximo possível, não deve exigir outra explicação.
Nawaz
38

Vou oferecer uma opinião um pouco ao contrário. Há muitas informações boas em cplusplus.com. Escolha até a morte e, sim, é claro que tem seus problemas, mas que site não? Certamente não este site . Pessoas que vivem em casas de vidro não devem atirar pedras. Também há muita desinformação aqui. Existem respostas aceitas que são totalmente erradas, com respostas reduzidas (algumas negativas!) Que são exatamente corretas.

Um problema do cplusplus.com é que ele é um site fechado; o mesmo vale para a maioria dos outros sites de referência mencionados. Isso vai de encontro a um site desenvolvido pela comunidade, como o Stack Overflow. Adquirir a capacidade de fazer edições confiáveis ​​não leva tanto tempo, e mesmo os novatos mais novos podem facilmente fazer sugestões de aprimoramento. Compare isso com cplusplus.com. Você é um novato perpétuo se não estiver na equipe deles. Mesmo se você for um membro importante do WG21, precisará passar pelo mecanismo de relatório por e-mail se encontrar um bug em algum lugar desse site. Anátema!

Neste site, seria uma solução desenvolver nossa própria referência C ++. Isso levaria um pouco de trabalho. Teríamos que ter cuidado para não sermos muito pedantes / técnicos; é óbvio que o cplusplus.com emprega pelo menos alguns editores técnicos que mantêm os pedantes afastados. Teríamos que manter as informações bem organizadas; as perguntas frequentes aqui não são bem organizadas. Também teríamos que ter muito cuidado para não jorrar muito diretamente do padrão; isso é ilegal.

David Hammen
fonte
7
Eu costumava frequentar o antigo cppreference.com, mas agora eles o reformularam em algo wiki-ish (está aberto para edição por todos?) ... e eu realmente não gosto mais. É difícil ver as informações importantes, eu acho. Falta apenas a gratificação imediata que recebo de cplusplus.com. Eu acho que.
29411 Kerrek SB
14
Uau! Eu vejo exatamente o oposto. Parei de frequentar o antigo cppreference.com porque achei difícil de ler e mal escrito. O novo cppreference.com parece ser um site comunitário, sem anúncios e que faz exatamente o que sugeri no meu último parágrafo.
David Hammen
1
Talvez fosse só eu, vou tentar outra vez. Eu acho que eu queria olhar para cima alguns <thread>ou <atomic>coisas e ficou "por favor escreva esta página" então eu desisti. Deixe-me verificar novamente! Ah, o suporte ao C ++ 0x seria, obviamente, um grande bônus!
Kerrek SB
10
"As pessoas que vivem em casas de vidro não devem jogar pedras". O SO não afirma ser (em parte) uma referência de biblioteca para C ++, como cplusplus.com/reference . Quando as pessoas fazem reivindicações aqui, elas citam o padrão para apoiá-las ou, se não o fazem, alguém aparece e preenche. Se estiverem erradas, você poderá ver o trabalho delas. Se cplusplus.com estiver errado, você acabou de escrever um código que falhará em alguma implementação de C ++ diferente daquela que o autor usou para produzir a "descrição detalhada de seus elementos". O problema é que o cplusplus.com é informal, mas escrito para parecer formal.
21711 Steve Joplin
4
SO é informal e escrito para parecer informal. Agora, se o cplusplus.com não se destina a ser um documentação precisa / material de referência e se você tiver perdido um aviso em algum lugar justo, suponha que pedras sejam jogadas nas pessoas que o usam dessa maneira e não no próprio site. Mas o ponto é que apenas porque o cplusplus.com diz algo sobre uma função C ++ não significa que é verdade, e vale a pena saber que, se você planeja usá-la como referência rápida. Eu o uso para procurar assinaturas de funções, mas nunca para definir um ponto importante, seja meu código conforme ou não.
21711 Steve Jobs (
14

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

Não menciona que "Se a cópia ocorre entre objetos que se sobrepõem, o comportamento é indefinido". (4.11.2.4 no padrão C89. Não tenho uma cópia em mãos do C90, que é o que C ++ 03 realmente se refere, mas eles devem diferir apenas em itens como numeração de páginas.)

Steve Jessop
fonte
Ah, a antiga biblioteca C ... legal.
Kerrek SB
6
Eles mencionam destination and source shall not overlap.
Sniper
2
@ Sniper "não deve se sobrepor" não é o mesmo que "o comportamento é indefinido". Seu comentário na verdade ilumina uma das falhas sutis e difundidas do cplusplus.com - parece certo, mas não está correto.
Andrew Henle
@ Sniper: Eu acho que provavelmente não disse isso quando eu fiz essa resposta em 2011. Eu teria tomado "não deve se sobrepor" como restrição suficiente nas entradas.
Steve Jessop
9

A documentação fornecida pelo cplusplus.com geralmente está incorreta ou incompleta.

Uma vez que esse exemplo seja, a atoidocumentação em cplusplus.com.

atoi
Na seção Return, não há menção sobre o valor de retorno 0 se nenhuma conversão puder ser executada enquanto estiver usando a função.

A seção de retorno do cplusplus.com declara "... Se o valor convertido estiver fora da faixa de valores representáveis ​​por um int, ele causará um comportamento indefinido."

Isso está correto, conforme o padrão " Se o valor numérico da sequência não puder ser representado em int, o comportamento será indefinido ".

No entanto, a seção não está cheia, pois não menciona 0 como valor de retorno, o que pode ser enganoso. A frase "... nenhuma conversão é executada e zero é retornado". é atendido antes no parágrafo de descrição, mas é essencial tê-lo na seção Retornar .

Muitos dos códigos-fonte de amostra fornecidos no cplusplus.com estão incorretos.
Muitos dos novatos que procuram essas referências são levados a cometer erros redundantes.

Para citar um exemplo:

EDIT: O exemplo que citei anteriormente estava incorreto.

Alok Save
fonte
5
Talvez ballant -> flagrante? No entanto, ballant é uma palavra francesa para "dangling", que pode ser apropriada para erros envolvendo ponteiros.
hardmath
Releia o exemplo do iterador ... não há comportamento indefinido.
Dennis Zickefoose
1
Você declarou "Muitos dos códigos-fonte de amostra fornecidos no cplusplus.com estão incorretos". e removeu o exemplo dizendo "O exemplo que citei anteriormente estava incorreto". - Por que você removeu o exemplo, então? :)
user2962533
De acordo com este site, o caso que você descreve resulta em um tipo de retorno indefinido, não em um comportamento indefinido. en.cppreference.com/w/cpp/string/byte/atoi ; no entanto, parece que o Cplusplus.com atualizou sua documentação para corresponder ao que você está dizendo. Evidentemente, eles respondem a solicitações da comunidade para correções. No entanto, não tenho certeza de qual site está mais correto, porque os dois em questão afirmam coisas muito diferentes.
precisa saber é o seguinte
Faz 9 anos desde que esta resposta foi publicada. Ainda se acredita que o Cplusplus.com contém uma quantidade significativa de informações incorretas ou incompletas?
Tyler Shellberg 11/03
3

A documentação para type_infotenta explicar typeidprimeiro, mas falha:

typeid pode ser aplicado diretamente aos tipos; nesse caso, ele retorna suas informações; Ou para objetos; nesse caso, ele retorna informações sobre o tipo do objeto.

Quando typeid é aplicado a um ponteiro não referenciado para um objeto de um tipo de classe polimórfica (uma classe que declara ou herda uma função virtual), ele considera seu tipo dinâmico (ou seja, o tipo do objeto mais derivado).

Agora, o segundo parágrafo já discorda do primeiro. In typeid(*ptr), typeidé aplicado a uma expressão. Isso é bastante essencial, uma vez que a noção statice os dynamictipos só fazem sentido no contexto da expressão, não nos objetos. Ele também perde casos comotypeid(foo()) .

Além disso, o segundo parágrafo omite referências. Eles também podem ter tipos estáticos diferentes do tipo dinâmico do objeto que fazem referência.

MSalters
fonte
Muito bom - as perguntas de RTTI surgem no SO com regularidade previsível. É bom saber o que não fazer referência.
Kerrek SB 29/06/11
3

A documentação std::pair<T1,T2>::operator==diz que ambos os elementos são testados quanto à igualdade. A documentação de std::pair<T1,T2>::operator<diz que os segundos elementos são considerados apenas se os primeiros elementos forem iguais.

A palavra "igual" aparece nos dois casos. No entanto, somente no primeiro caso isso realmente significa T::operator==. No segundo caso, médias iguais!(a.first<b.first || b.first<a.first)

MSalters
fonte
Isso é obrigatório ou a biblioteca pode ser usada gratuitamente operator==no segundo caso, se o operador estiver disponível?
Kerrek SB
1
Obrigatório. O padrão C ++ não combina operator==e operator<.
MSalters