Perché non dovrei #include <bits / stdc ++. H>?


267

Ho pubblicato una domanda con il mio codice la cui unica #includedirettiva era la seguente:

#include <bits/stdc++.h>

Il mio insegnante mi ha detto di farlo, ma nella sezione commenti sono stato informato che non avrei dovuto.

Perché?


72
Huh. Avrei dovuto sapere che ci sarebbe stata una versione di inclusione using namespace std;là fuori da qualche parte.
user4581301

1
perché esiste questa intestazione? sicuramente nessuno degli standard include effettivamente questo, dal momento che porterebbe un sacco di spazzatura? e se non è incluso da nessuno del pubblico include ... allora perché viene spedito nella distribuzione?
Chris Beck,

10
@ChrisBeck: è un dettaglio di implementazione. Non fa parte dell '"API pubblica" o pensata per l'uso. Ma deve ancora essere spedito altrimenti non funzionerebbe. Lo standard include potrebbe non usarlo singolarmente ma è lì per l'uso in intestazioni precompilate. Vedi il commento in alto, che dice: "Questo è un file di implementazione per un'intestazione precompilata". .
Razze di leggerezza in orbita

1
@LightnessRacesinOrbit Se non dovresti usarlo da solo, in che modo la sua esistenza aiuta con PCH? O gcc è abbastanza intelligente da passare automaticamente ad esso per scopi di PCH in alcune circostanze?
Daniel H,

2
@LightnessRacesinOrbit "Non fa parte dell '" API pubblica "o pensata per l'uso." Totalmente sbagliato, è inteso per uso pubblico, come intestazione precompilata. Libstdc ++ (pre) compila e installa una versione precompilata di quell'intestazione, quindi se la includi, G ++ includerà bits/stdc++.h.gchinvece la versione precompilata. Esiste perché deve esistere in modo da poter generare la versione precompilata di esso.
Jonathan Wakely,

Risposte:


311

Includere <bits/stdc++.h>sembra essere una cosa sempre più comune da vedere su Stack Overflow, forse qualcosa di nuovo aggiunto a un curriculum nazionale nell'anno accademico in corso.

Immagino che i vantaggi siano vagamente dati così:

  • Hai solo bisogno di scrivere una #includeriga
  • Non è necessario cercare in quale intestazione standard è presente tutto

Sfortunatamente, questo è un trucco pigro, che nomina direttamente un'intestazione interna GCC invece di singole intestazioni standard come <string>, <iostream>e <vector>. Rovina la portabilità e favorisce abitudini terribili.

Gli svantaggi includono:

  • Probabilmente funzionerà solo su quel compilatore
  • Non hai idea di cosa farà quando lo usi, perché i suoi contenuti non sono impostati da uno standard
  • Anche solo l'aggiornamento del compilatore alla sua prossima versione potrebbe interrompere il programma
  • Ogni singola intestazione standard deve essere analizzata e compilata insieme al codice sorgente, che è lento e si traduce in un eseguibile ingombrante con determinate impostazioni di compilazione

Non farlo!


Maggiori informazioni:

Esempio del motivo per cui Quora è cattiva:


78
"forse qualcosa di nuovo aggiunto a un curriculum nazionale nell'anno accademico in corso" Blind leader the blind :(
Reinstate Monica

14
@KubaOber: esattamente.
Razze di leggerezza in orbita,

33
Sono appena arrivato da un wormhole in un'altra domanda, molto bene. Ciò che peggiora questa abitudine di insegnamento è che di solito è seguito da un diretto using namesapce std;. Sono presenti solo due righe e praticamente viene utilizzato ogni identificatore piacevole. Incredibilmente frustrante vederlo insegnare.
StoryTeller - Unslander Monica,

6
Sull'esempio di quora, potrebbe essere cambiato nel tempo. Ho visitato la pagina oggi e sia i pro che i contro di <bits / stdc ++. H> dove sono elencati nel contesto specifico dei concorsi di programmazione online. Trovo la loro conclusione ok-ish.
YSC

4
@EvgeniSergeev: 2 KiB è un sacco di codice, dati, informazioni sui simboli, ecc., Quando si cerca di determinarne l'effetto. Capisci tutto ciò che viene aggiunto? Per il tuo compilatore? La versione attuale? Tutte le versioni in mezzo? Tutte le versioni future? Se devi decidere tra convenienza e correttezza, esiste un'unica opzione valida.
Indispensabile il

48

Perché? Perché è usato come se dovesse essere un'intestazione standard C ++, ma nessuno standard lo menziona. Quindi il tuo codice non è portatile per costruzione. Non troverai alcuna documentazione per questo su cppreference . Quindi potrebbe anche non esistere. È frutto della fantasia di qualcuno :)

Ho scoperto - con mio orrore e incredulità - che esiste un noto sito di tutorial in cui ogni esempio di C ++ sembra includere questa intestazione . Il mondo è pazzo. Questa è la prova.


A chiunque scriva tali "tutorial"

Si prega di smettere di usare questa intestazione. Dimenticalo. Non propagare questa follia. Se non sei disposto a capire perché farlo è sbagliato , credimi . Non sto bene essendo trattato come una figura di autorità su qualcosa, e probabilmente ne sarò pieno per metà del tempo, ma farò un'eccezione solo in questo caso. Dichiaro di sapere di cosa sto parlando qui. Accettami la mia parola. Ti imploro.

PS Posso ben immaginare l'abominevole "standard di insegnamento" in cui questa malvagia idea potrebbe aver avuto luogo e le circostanze che l'hanno portata. Solo perché sembrava esserci un'esigenza pratica, non lo rende accettabile, nemmeno a posteriori.

PPS No, non c'era bisogno pratico per questo. Non ci sono molte intestazioni standard C ++ e sono ben documentate. Se insegni, stai facendo un cattivo servizio ai tuoi studenti aggiungendo tale "magia". Produrre programmatori con una mentalità magica è l'ultima cosa che vogliamo. Se hai bisogno di offrire agli studenti un sottoinsieme di C ++ per semplificare la loro vita, crea un volantino con la breve lista di intestazioni applicabili al corso che insegni e con una documentazione concisa per i costrutti della biblioteca che prevedi vengano utilizzati dagli studenti.


35

C'è un sito Stack Stack chiamato Programming Puzzles & Code Golf . I puzzle di programmazione su quel sito si adattano a questa definizione di puzzle :

un giocattolo, un problema o altro congegno progettato per divertire presentando difficoltà da risolvere con l'ingegno o lo sforzo del paziente.

Sono progettati per divertire e non nel modo in cui un programmatore di lavoro potrebbe essere divertito da un problema del mondo reale riscontrato nel suo lavoro quotidiano.

Code Golf è "un tipo di competizione di programmazione informatica ricreativa in cui i partecipanti si sforzano di ottenere il codice sorgente più breve possibile che implementa un determinato algoritmo". Nelle risposte sul sito PP&CG, vedrai che le persone specificano il numero di byte nelle loro risposte. Quando trovano il modo di radere qualche byte, cancellano il numero originale e registrano quello nuovo.

Come ci si potrebbe aspettare, il golf di codice premia l'abuso estremo del linguaggio di programmazione. Nomi variabili di una lettera. Nessuno spazio bianco. Uso creativo delle funzioni di libreria. Funzionalità non documentate. Pratiche di programmazione non standard. Hack spaventosi.

Se un programmatore ha inviato una richiesta pull al lavoro contenente un codice di tipo golf, verrebbe respinto. I loro colleghi avrebbero riso di loro. Il loro manager sarebbe passato dalla loro scrivania per una chat. Anche così, i programmatori si divertono inviando risposte a PP&CG.

Cosa c'entra questo stdc++.h? Come altri hanno sottolineato, usarlo è pigro. È non portatile, quindi non sai se funzionerà sul tuo compilatore o sulla prossima versione del compilatore. Favorisce le cattive abitudini. È non standard, quindi il comportamento del tuo programma potrebbe differire da quello che ti aspetti. Potrebbe aumentare i tempi di compilazione e le dimensioni eseguibili.

Queste sono tutte obiezioni valide e corrette. Allora perché qualcuno dovrebbe usare questa mostruosità?

Si scopre che ad alcune persone piace programmare enigmi senza il codice golf . Si riuniscono e competono in eventi come ACM-ICPC, Google Code Jam e Facebook Hacker Cup, o su siti come Topcoder e Codeforces. Il loro rango si basa sulla correttezza del programma, sulla velocità di esecuzione e sulla velocità con cui inviano una soluzione. Per massimizzare la velocità di esecuzione, molti partecipanti usano C ++. Per massimizzare la velocità di codifica, alcuni usano stdc++.h.

È una buona idea? Controlliamo l'elenco degli svantaggi. Portabilità? Non importa dal momento che questi eventi di codifica utilizzano una specifica versione del compilatore che i concorrenti conoscono in anticipo. Conformità agli standard? Non pertinente per un blocco di codice la cui vita utile è inferiore a un'ora. Tempo di compilazione e dimensione eseguibile? Questi non fanno parte della rubrica dei punteggi del concorso.

Quindi siamo rimasti con cattive abitudini. Questa è un'obiezione valida. Usando questo file di intestazione, i concorrenti evitano la possibilità di sapere quale file di intestazione standard definisce la funzionalità che stanno usando nel loro programma. Quando scrivono il codice del mondo reale (e non lo usano stdc++.h) dovranno trascorrere del tempo a cercare queste informazioni, il che significa che saranno meno produttivi. Questo è il rovescio della medaglia con la pratica stdc++.h.

Ciò solleva la questione del perché valga la pena prendere parte alla programmazione competitiva se incoraggia cattive abitudini come l'uso stdc++.he la violazione di altri standard di codifica. Una risposta è che le persone lo fanno per lo stesso motivo per cui pubblicano programmi su PP&CG: alcuni programmatori trovano piacevole usare le loro capacità di programmazione in un contesto simile a un gioco.

Quindi la domanda sull'opportunità di utilizzare stdc++.hdipende dal fatto che i vantaggi della velocità di codifica in un concorso di programmazione superino le cattive abitudini che si potrebbero sviluppare usandolo.

Questa domanda chiede: "Perché non dovrei #includere <bits/stdc++.h>?" Mi rendo conto che è stato chiesto e risposto per esprimere un punto, e la risposta accettata è intesa come l'unica vera risposta a questa domanda. Ma la domanda non è "Perché non dovrei includere # <bits/stdc++.h>nel codice di produzione?" Pertanto, penso che sia ragionevole considerare altri scenari in cui la risposta potrebbe essere diversa.


5
Ho già votato, ma potrebbe valere la pena sottolineare che "per divertimento" è una buona ragione per prendere parte alla programmazione competitiva. D'altro canto "impressionare un potenziale datore di lavoro" non lo è - danneggerà attivamente il tuo caso con me.
Martin Bonner supporta Monica il

2
@MartinBonner So che alcuni responsabili delle assunzioni vedono l'esperienza di programmazione competitiva come una bandiera rossa. Ma fino a quando le principali aziende produttrici di software utilizzeranno problemi di stile CP nelle loro interviste e organizzeranno concorsi di programmazione per trovare nuove reclute, CP continuerà a essere popolare tra gli aspiranti sviluppatori.
RedGreenCode

@RedGreenCode Non sono un manager (grazie a $ DEITY), ma a volte ho influenza sulle assunzioni di assunzione. E vedo sicuramente ogni riferimento alla "programmazione competitiva" come un'enorme bandiera rossa, non un vantaggio.
Jesper Juhl,

3
@JesperJuhl Se gli intervistatori tecnici della tua azienda utilizzano puzzle algoritmici nelle loro interviste (come molti fanno), ciò offre ai candidati con esperienza di programmazione competitiva un vantaggio. Forse la scelta razionale per i candidati è quella di partecipare al CP ma evitare di menzionarlo nel loro curriculum / CV.
RedGreenCode

2
Anche se è vero che questa intestazione può essere utilizzata in qualche programmazione competitiva, non è esattamente da dove proviene. Veniva da un'aula. E chiunque insegnasse in quell'aula ebbe abbastanza influenza da inquinare - attraverso la cascata che ne seguì - decine se non centinaia di migliaia di studenti (educando insegnanti e colleghi che poi, inconsapevolmente, avevano diffuso quella malattia). E ora quegli studenti stanno anche scrivendo tutorial in un posto dove andare per tutorial. Voglio solo piangere in un angolo. I siti di programmazione competitiva dovrebbero avere una regex per rifiutare qualsiasi intestazione non standard .
Ripristina Monica il

9

Da N4606, Working Draft, Standard per il linguaggio di programmazione C ++:

17.6.1.2 Header [header]

  1. Ogni elemento della libreria standard C ++ è dichiarato o definito (come appropriato) in un'intestazione.

  2. La libreria standard C ++ fornisce 61 intestazioni di libreria C ++, come mostrato nella Tabella 14.

Tabella 14 - Intestazioni della libreria 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>

Non ci sono <bit / stdc ++. H> lì. Ciò non sorprende, dal momento che le intestazioni <bits / ...> sono dettagli di implementazione e di solito portano un avvertimento:

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

<bits / stdc ++. h> porta anche un avvertimento:

*  This is an implementation file for a precompiled header.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.