Por que não deveria #include <bits / stdc ++. H>?

Aug 05 2015

Eu postei uma pergunta com meu código cuja única #includediretiva era a seguinte:

#include <bits/stdc++.h>

Meu professor me disse para fazer isso, mas na seção de comentários fui informado que não deveria.

Por quê?

Respostas

349 LightnessRacesinOrbit Aug 05 2015 at 00:57

Incluir <bits/stdc++.h>parece ser uma coisa cada vez mais comum de se ver no Stack Overflow, talvez algo recentemente adicionado a um currículo nacional no ano acadêmico atual.

Eu imagino que as vantagens são dadas vagamente assim:

  • Você só precisa escrever uma #includelinha
  • Você não precisa procurar em qual cabeçalho padrão tudo está

Infelizmente, este é um hack preguiçoso, nomeando um cabeçalho interno do GCC diretamente em vez de cabeçalhos padrão individuais como <string>, <iostream>e <vector>. Isso arruína a portabilidade e promove hábitos terríveis.

As desvantagens incluem:

  • Provavelmente só funcionará naquele compilador
  • Você não tem ideia do que ele fará ao usá-lo, porque seu conteúdo não é definido por um padrão
  • Mesmo apenas atualizando seu compilador para sua próxima versão pode quebrar seu programa
  • Cada cabeçalho padrão deve ser analisado e compilado junto com seu código-fonte, o que é lento e resulta em um executável volumoso sob certas configurações de compilação

Não faça isso!


Mais Informações:

Exemplo de por que o Quora é ruim:

67 UnslanderMonica Aug 06 2015 at 23:50

Por quê? Porque ele é usado como se fosse um cabeçalho padrão C ++, mas nenhum padrão o menciona. Portanto, seu código não é portável por construção. Você não encontrará nenhuma documentação para isso em cppreference . Portanto, pode muito bem não existir. É uma invenção da imaginação de alguém :)

Eu descobri - para meu horror e descrença - que existe um site de tutorial bem conhecido onde todos os exemplos de C ++ parecem incluir este cabeçalho . O mundo está louco. Essa é a prova.


Para quem está escrevendo esses "tutoriais"

Por favor, pare de usar este cabeçalho. Esqueça isso. Não propague essa insanidade. Se você não quer entender por que fazer isso é errado , acredite em mim. Não estou bem em ser tratado como uma figura de autoridade em qualquer coisa, e provavelmente estou cheio disso na metade do tempo, mas abrirei uma exceção apenas neste caso. Eu afirmo que sei do que estou falando aqui. Acredite na minha palavra. Eu te imploro.

PS Posso muito bem imaginar o abominável "padrão de ensino" em que essa ideia perversa pode ter ocorrido e as circunstâncias que levaram a ela. Só porque parecia haver uma necessidade prática, não o torna aceitável - nem mesmo em retrospecto.

PPS Não, não havia necessidade prática para isso. Não há muitos cabeçalhos padrão C ++ e eles estão bem documentados. Se você ensina, está prestando um péssimo serviço aos seus alunos ao adicionar essa "magia". Produzir programadores com uma mentalidade mágica é a última coisa que queremos. Se você precisa oferecer aos alunos um subconjunto de C ++ para tornar sua vida mais fácil, apenas produza um folheto com a pequena lista de cabeçalhos aplicáveis ​​ao curso que você ensina e com documentação concisa para as construções de biblioteca que você espera que os alunos usem.

45 RedGreenCode Apr 23 2019 at 08:09

Há um site Stack Exchange chamado Programming Puzzles & Code Golf . Os quebra - cabeças de programação desse site se encaixam nesta definição de quebra - cabeça :

um brinquedo, problema ou outro artifício projetado para divertir, apresentando dificuldades a serem resolvidas pela engenhosidade ou esforço do paciente.

Eles são projetados para divertir, e não da maneira que um programador profissional pode se divertir com um problema do mundo real encontrado em seu trabalho diário.

Code Golf é "um tipo de competição recreativa de programação de computador em que os participantes se esforçam para obter o código-fonte mais curto possível que implemente um determinado algoritmo". Nas respostas do site PP&CG, você verá que as pessoas especificam o número de bytes em suas respostas. Quando encontrarem uma maneira de cortar alguns bytes, eliminarão o número original e registrarão o novo.

Como você pode esperar, o golfe de código recompensa o abuso extremo da linguagem de programação. Nomes de variáveis ​​de uma letra. Sem espaços em branco. Uso criativo das funções da biblioteca. Recursos não documentados. Práticas de programação não padronizadas. Hackers terríveis.

Se um programador enviar uma solicitação pull no trabalho contendo um código de estilo golfe, ela seria rejeitada. Seus colegas de trabalho riam deles. O gerente deles passava por sua mesa para um bate-papo. Mesmo assim, os programadores se divertem enviando respostas ao PP&CG.

O que isso tem a ver stdc++.h? Como outros apontaram, usá-lo é preguiçoso. Ele não é portável, então você não sabe se funcionará no seu compilador ou na próxima versão do seu compilador. Isso promove maus hábitos. Não é padrão, então o comportamento do seu programa pode ser diferente do que você espera. Isso pode aumentar o tempo de compilação e o tamanho do executável.

Todas essas objeções são válidas e corretas. Então, por que alguém usaria essa monstruosidade?

Acontece que algumas pessoas gostam de programar quebra-cabeças sem o código de golfe . Eles se reúnem e competem em eventos como ACM-ICPC, Google Code Jam e Facebook Hacker Cup, ou em sites como Topcoder e Codeforces. Sua classificação é baseada na exatidão do programa, na velocidade de execução e na rapidez com que enviam uma solução. Para maximizar a velocidade de execução, muitos participantes usam C ++. Para maximizar a velocidade de codificação, alguns deles usam stdc++.h.

É uma boa ideia? Vamos verificar a lista de desvantagens. Portabilidade? Não importa, pois esses eventos de codificação usam uma versão do compilador específica que os competidores conhecem com antecedência. Conformidade com os padrões? Não é relevante para um bloco de código cuja vida útil seja inferior a uma hora. Tempo de compilação e tamanho do executável? Isso não faz parte da rubrica de pontuação do concurso.

Portanto, ficamos com maus hábitos. Esta é uma objeção válida. Ao usar este arquivo de cabeçalho, os competidores estão evitando a chance de aprender qual arquivo de cabeçalho padrão define a funcionalidade que eles estão usando em seu programa. Quando estão escrevendo código do mundo real (e não usando stdc++.h), eles terão que gastar tempo procurando essas informações, o que significa que serão menos produtivos. Essa é a desvantagem de praticar com stdc++.h.

Isso levanta a questão de por que vale a pena participar da programação competitiva, se isso incentiva hábitos ruins, como usar stdc++.he violar outros padrões de codificação. Uma resposta é que as pessoas fazem isso pelo mesmo motivo que publicam programas no PP&CG: alguns programadores acham divertido usar suas habilidades de codificação em um contexto semelhante ao de um jogo.

Portanto, a questão de usar ou não stdc++.hse resume a se os benefícios da velocidade de codificação em um concurso de programação superam os maus hábitos que alguém pode desenvolver ao usá-lo.

Esta pergunta pergunta: "Por que eu não deveria #incluir <bits/stdc++.h>?" Eu percebo que foi perguntado e respondido para fazer um ponto, e a resposta aceita pretende ser a Resposta Verdadeira para esta pergunta. Mas a questão não é "Por que não devo #incluir <bits/stdc++.h>no código de produção?" Portanto, acho razoável considerar outros cenários em que a resposta pode ser diferente.

12 Bulletmagnet Nov 03 2019 at 18:39

De N4606, Working Draft, Standard for Programming Language C ++:

17.6.1.2 Cabeçalhos [cabeçalhos]

  1. Cada elemento da biblioteca padrão C ++ é declarado ou definido (conforme apropriado) em um cabeçalho.

  2. A biblioteca padrão C ++ fornece 61 cabeçalhos de biblioteca C ++, conforme mostrado na Tabela 14.

Tabela 14 - cabeçalhos de biblioteca C ++

<algorithm> <future> <numeric> <strstream>
<any> <initializer_list> <optional> <system_error>
<array> <iomanip> <ostream> <thread>
<atomic> <ios> <queue> <tuple>
<bitset> <iosfwd> <random> <type_traits>
<chrono> <iostream> <ratio> <typeindex>
<codecvt> <istream> <regex> <typeinfo>
<complex> <iterator> <scoped_allocator> <unordered_map>
<condition_variable> <limits> <set> <unordered_set>
<deque> <list> <shared_mutex> <utility>
<exception> <locale> <sstream> <valarray>
<execution> <map> <stack> <variant>
<filesystem> <memory> <stdexcept> <vector>
<forward_list> <memory_resorce> <streambuf>
<fstream> <mutex> <string>
<functional> <new> <string_view>

Não há <bits / stdc ++. H> lá. Isso não é surpreendente, uma vez que os cabeçalhos <bits / ...> são detalhes de implementação e geralmente contêm um aviso:

*  This is an internal header file, included by other library headers.
*  Do not attempt to use it directly. 

<bits / stdc ++. h> também traz um aviso:

*  This is an implementation file for a precompiled header.
2 YunfeiChen Jul 08 2020 at 07:20

O motivo pelo qual não usamos:

#include <bits/stdc++.h>

é por causa da eficiência. Deixe-me fazer uma analogia: para aqueles de vocês que conhecem Java: se você perguntasse ao seu instrutor se o seguinte era uma boa ideia, a menos que ele fosse um mau instrutor, eles diriam não:

import java.*.*

O #include ... faz basicamente a mesma coisa ... Essa não é a única razão para não usá-lo, mas é uma das principais razões para não usá-lo. Para uma analogia da vida real: imagine que você tivesse uma biblioteca e quisesse pegar alguns livros emprestados dela, você mudaria a biblioteca inteira para perto de sua casa? Seria caro e ineficaz. Se você só precisa de 5 livros, então tire apenas 5 ... Não a biblioteca inteira ...

#include <bits/stdc++.h>

Parece conveniente para a aparência do programa Eu só preciso digitar uma instrução de inclusão e funciona, a mesma coisa com a movimentação de uma biblioteca inteira, olha, eu só preciso mover uma biblioteca inteira em vez de 5 livros, um por um. Parece conveniente para você, isto é, para a pessoa que realmente tem que fazer a mudança ?? Nem tanto, e adivinhe o que em C ++ a pessoa que está fazendo a movimentação será o seu computador ... O computador não gostará de mover a biblioteca inteira para cada arquivo de origem que você escrever:) .....