Mengapa saya tidak memasukkan # bits / stdc ++. H>?

267

Saya memposting pertanyaan dengan kode saya yang hanya #includedirektif sebagai berikut:

#include <bits/stdc++.h>

Guru saya menyuruh saya melakukan ini, tetapi di bagian komentar saya diberi tahu bahwa saya tidak boleh melakukannya.

Mengapa?

Lightness Races di Orbit
sumber
72
Hah. Aku seharusnya tahu akan ada versi menyertakan di using namespace std;luar sana.
user4581301
1
mengapa tajuk ini bahkan ada? pasti tidak ada standar yang termasuk sebenarnya termasuk ini, karena akan membawa banyak sampah? dan jika tidak termasuk oleh publik termasuk ... lalu mengapa itu dikirim dalam distribusi?
Chris Beck
10
@ ChrisBeck: Ini adalah detail implementasi. Itu bukan bagian dari "API publik" atau dimaksudkan untuk digunakan. Tetapi masih harus dikirim jika tidak tidak ada yang berhasil. Standar mencakup mungkin tidak menggunakannya secara individual tetapi ada untuk digunakan dalam header yang dikompilasi. Lihat komentar di atas, yang mengatakan: "Ini adalah file implementasi untuk header yang dikompilasi." .
Lightness Races dalam Orbit
1
@LightnessRacesinOrbit Jika Anda tidak seharusnya menggunakannya sendiri, bagaimana keberadaannya membantu PCH? Atau gcc cukup pintar untuk secara otomatis beralih ke itu untuk keperluan PCH dalam beberapa keadaan?
Daniel H
2
@LightnessRacesinOrbit "Ini bukan bagian dari" API publik "atau dimaksudkan untuk digunakan." Benar-benar salah, ini dimaksudkan untuk penggunaan umum, sebagai header yang dikompilasi. Libstdc ++ (pre) mengkompilasi dan menginstal versi yang sudah dikompilasi dari header itu, jadi jika Anda memasukkannya maka G ++ akan benar-benar memasukkan bits/stdc++.h.gch, versi yang dikompilasi. Itu ada karena harus ada sehingga versi yang telah dikompilasi dapat dihasilkan.
Jonathan Wakely

Jawaban:

311

Termasuk <bits/stdc++.h>tampaknya menjadi hal yang semakin umum untuk dilihat di Stack Overflow, mungkin sesuatu yang baru ditambahkan ke kurikulum nasional di tahun akademik saat ini.

Saya membayangkan keuntungan yang diberikan secara samar:

  • Anda hanya perlu menulis satu #includebaris
  • Anda tidak perlu mencari header standar apa yang ada di dalamnya

Sayangnya, ini adalah hack malas, menamai header internal GCC langsung daripada header standar individu seperti <string>, <iostream>dan <vector>. Ini merusak portabilitas dan menumbuhkan kebiasaan buruk.

Kerugiannya termasuk:

  • Mungkin hanya akan bekerja pada kompiler itu
  • Anda tidak tahu apa yang akan dilakukan ketika Anda menggunakannya, karena isinya tidak ditentukan oleh standar
  • Bahkan hanya meningkatkan kompiler Anda ke versi berikutnya sendiri dapat merusak program Anda
  • Setiap header standar tunggal harus diuraikan dan dikompilasi bersama dengan kode sumber Anda, yang lambat dan menghasilkan eksekusi besar di bawah pengaturan kompilasi tertentu

Jangan lakukan itu!


Informasi lebih lanjut:

Contoh mengapa Quora buruk:

Lightness Races di Orbit
sumber
78
"mungkin sesuatu yang baru ditambahkan ke kurikulum nasional di tahun akademik saat ini" Buta memimpin orang buta :(
Reinstate Monica
14
@KubaOber: Tepat.
Lightness Races in Orbit
33
Baru saja datang ke sini melalui lubang cacing di pertanyaan lain, sangat bagus. Apa yang membuat kebiasaan mengajar ini lebih buruk adalah bahwa biasanya diikuti oleh langsung using namesapce std;. Hanya dua baris dan hampir setiap pengenal yang bagus digunakan. Sangat frustasi melihatnya diajarkan.
StoryTeller - Unslander Monica
6
Tentang contoh quora, mungkin telah bergeser seiring waktu. Saya telah mengunjungi halaman hari ini dan pro dan kontra dari <bits / stdc ++. H> di mana tercantum dalam konteks spesifik dari kontes pemrograman online. Saya menemukan kesimpulan mereka ok-ish.
YSC
4
@ EvgeniSergeev: 2KiB adalah banyak kode, data, informasi simbol, dll., Ketika mencoba untuk menentukan efeknya. Apakah Anda memahami semua yang ditambahkan? Untuk kompiler Anda? Rilis saat ini? Semua rilis di antaranya? Semua rilis mendatang? Jika Anda perlu memutuskan antara kenyamanan dan kebenaran, hanya ada satu opsi yang valid.
IInspectable
48

Mengapa? Karena digunakan seolah-olah itu seharusnya header standar C ++, tetapi tidak ada standar yang menyebutkannya. Jadi kode Anda tidak portabel dengan konstruksi. Anda tidak akan menemukan dokumentasi untuk itu di cppreference . Jadi mungkin juga tidak ada. Itu isapan jempol dari imajinasi seseorang :)

Saya telah menemukan - yang membuat saya ngeri dan tidak percaya - bahwa ada situs tutorial terkenal di mana setiap contoh C ++ sepertinya menyertakan header ini . Dunia ini gila. Itu buktinya.


Untuk siapa pun yang menulis "tutorial" seperti itu

Harap berhenti menggunakan tajuk ini. Lupakan saja. Jangan menyebarkan kegilaan ini. Jika Anda tidak mau mengerti mengapa melakukan ini salah , terima kata-kata saya. Saya tidak apa-apa diperlakukan sebagai figur otoritas pada apa pun, dan saya mungkin sudah separuh waktu, tetapi saya akan membuat pengecualian dalam kasus ini saja. Saya mengklaim bahwa saya tahu apa yang saya bicarakan di sini. Bawa saya pada kata saya. Saya mohon Anda.

PS Saya bisa membayangkan "standar pengajaran" yang keji di mana ide jahat ini mungkin terjadi, dan keadaan yang menyebabkannya. Hanya karena tampaknya ada kebutuhan praktis untuk itu tidak membuatnya diterima - bahkan dalam retrospeksi.

PPS Tidak, tidak ada kebutuhan praktis untuk itu. Tidak ada banyak header standar C ++, dan mereka didokumentasikan dengan baik. Jika Anda mengajar, Anda merugikan siswa dengan menambahkan "sihir" seperti itu. Memproduksi programmer dengan pola pikir magis adalah hal terakhir yang kami inginkan. Jika Anda perlu menawarkan kepada siswa subset C ++ untuk membuat hidup mereka lebih mudah, cukup buat selebaran dengan daftar pendek tajuk yang berlaku untuk kursus yang Anda ajarkan, dan dengan dokumentasi ringkas untuk konstruksi perpustakaan yang Anda harapkan akan digunakan siswa.

Pasang kembali Monica
sumber
35

Ada situs Stack Exchange yang disebut Programming Puzzles & Code Golf . The teka-teki pemrograman di situs yang sesuai definisi teka-teki :

mainan, masalah, atau alat lain yang dirancang untuk menghibur dengan menghadirkan kesulitan yang harus diselesaikan dengan kecerdikan atau upaya pasien.

Mereka dirancang untuk menghibur, dan tidak sedemikian rupa sehingga programmer yang bekerja mungkin terhibur dengan masalah dunia nyata yang dihadapi dalam pekerjaan sehari-hari mereka.

Code Golf adalah "jenis kompetisi pemrograman komputer rekreasi di mana peserta berusaha untuk mencapai kode sumber sesingkat mungkin yang mengimplementasikan algoritma tertentu." Di jawaban di situs PP&CG, Anda akan melihat orang-orang menentukan jumlah byte dalam jawaban mereka. Ketika mereka menemukan cara untuk memangkas beberapa byte, mereka akan mencoret nomor aslinya dan mencatat yang baru.

Seperti yang Anda duga, kode golf memberikan penghargaan pada penyalahgunaan bahasa pemrograman ekstrem. Nama variabel satu huruf. Tanpa spasi putih. Penggunaan fungsi perpustakaan secara kreatif. Fitur tidak berdokumen. Praktek pemrograman yang tidak standar. Retas yang mengerikan.

Jika seorang programmer mengajukan permintaan tarik di tempat kerja yang berisi kode gaya golf, itu akan ditolak. Rekan kerja mereka akan menertawakan mereka. Manajer mereka akan mampir di meja mereka untuk mengobrol. Meski begitu, pemrogram menghibur diri dengan mengirimkan jawaban ke PP&CG.

Apa hubungannya ini stdc++.h? Seperti yang orang lain tunjukkan, menggunakannya itu malas. Ini non-portabel, jadi Anda tidak tahu apakah itu akan bekerja pada kompiler Anda atau versi kompiler Anda berikutnya. Ini menumbuhkan kebiasaan buruk. Ini bukan standar, jadi perilaku program Anda mungkin berbeda dari yang Anda harapkan. Ini dapat meningkatkan waktu kompilasi dan ukuran yang dapat dieksekusi.

Ini semua adalah keberatan yang sah dan benar. Jadi mengapa ada orang yang menggunakan kebodohan ini?

Ternyata beberapa orang menyukai pemrograman puzzle tanpa kode golf . Mereka berkumpul dan bersaing di acara-acara seperti ACM-ICPC, Google Code Jam, dan Facebook Hacker Cup, atau di situs-situs seperti Topcoder dan Codeforces. Peringkat mereka didasarkan pada kebenaran program, kecepatan eksekusi, dan seberapa cepat mereka mengirimkan solusi. Untuk memaksimalkan kecepatan eksekusi, banyak peserta menggunakan C ++. Untuk memaksimalkan kecepatan pengkodean, beberapa di antaranya digunakan stdc++.h.

Apakah ini ide yang bagus? Mari kita periksa daftar kerugiannya. Portabilitas? Tidak masalah karena acara pengkodean ini menggunakan versi kompiler khusus yang diketahui oleh para kontestan sebelumnya. Kepatuhan standar? Tidak relevan untuk satu blok kode yang masa pakainya kurang dari satu jam. Kompilasi waktu dan ukuran yang dapat dieksekusi? Ini bukan bagian dari rubrik penilaian kontes.

Jadi kita dibiarkan dengan kebiasaan buruk. Ini adalah keberatan yang sah. Dengan menggunakan file header ini, kontestan menghindari kesempatan untuk mengetahui file header standar mana yang mendefinisikan fungsionalitas yang mereka gunakan dalam program mereka. Ketika mereka menulis kode dunia nyata (dan tidak menggunakan stdc++.h) mereka harus menghabiskan waktu mencari informasi ini, yang berarti mereka akan kurang produktif. Itulah kelemahan berlatih dengan stdc++.h.

Hal ini menimbulkan pertanyaan mengapa layak untuk ikut serta dalam pemrograman kompetitif jika mendorong kebiasaan buruk seperti menggunakan stdc++.hdan melanggar standar pengkodean lainnya. Salah satu jawabannya adalah bahwa orang melakukannya karena alasan yang sama dengan mereka memposting program pada PP&CG: beberapa programmer merasa senang menggunakan keterampilan pengkodean mereka dalam konteks seperti gim.

Jadi pertanyaan apakah akan digunakan stdc++.hturun ke apakah manfaat kecepatan pengkodean dalam kontes pemrograman melebihi kebiasaan buruk yang mungkin dikembangkan dengan menggunakannya.

Pertanyaan ini bertanya: "Mengapa saya tidak harus # mencantumkan <bits/stdc++.h>?" Saya menyadari bahwa itu ditanyakan dan dijawab untuk menegaskan, dan jawaban yang diterima dimaksudkan sebagai Satu Jawaban Sejati untuk pertanyaan ini. Tetapi pertanyaannya bukan "Mengapa saya tidak memasukkan # <bits/stdc++.h>kode produksi?" Karena itu, saya pikir masuk akal untuk mempertimbangkan skenario lain di mana jawabannya mungkin berbeda.

RedGreenCode
sumber
5
Saya sudah memilih, tetapi mungkin perlu menunjukkan bahwa "untuk bersenang-senang" adalah alasan yang baik untuk mengambil bagian dalam pemrograman kompetitif. Di sisi lain "untuk mengesankan majikan potensial" tidak - itu akan secara aktif membahayakan kasus Anda dengan saya.
Martin Bonner mendukung Monica
2
@ MartinBonner Saya tahu beberapa manajer perekrutan melihat pengalaman pemrograman kompetitif sebagai tanda bahaya. Tetapi selama perusahaan perangkat lunak top menggunakan masalah gaya-CP dalam wawancara mereka dan menjalankan kontes pemrograman untuk menemukan rekrutmen baru, CP akan terus menjadi populer di kalangan calon pengembang.
RedGreenCode
@RedGreenCode Saya bukan seorang manajer (terima kasih $ DEITY), tapi kadang-kadang saya memiliki pengaruh dalam mempekerjakan keinginan. Dan saya pasti melihat referensi untuk "pemrograman kompetitif" sebagai bendera merah besar - bukan keuntungan.
Jesper Juhl
3
@JesperJuhl Jika pewawancara teknis di perusahaan Anda menggunakan teka-teki algoritmik dalam wawancara mereka (seperti yang dilakukan banyak orang), hal itu memberikan keuntungan bagi kandidat dengan pengalaman pemrograman kompetitif. Mungkin pilihan rasional untuk kandidat adalah untuk berpartisipasi dalam CP tetapi hindari menyebutkannya di resume / CV mereka.
RedGreenCode
2
Meskipun benar bahwa tajuk ini dapat digunakan dalam beberapa pemrograman kompetitif, itu tidak cukup dari mana asalnya. Itu berasal dari ruang kelas. Dan siapa pun yang mengajar di kelas itu memiliki pengaruh yang cukup untuk mencemari - melalui kaskade yang mengikuti - puluhan atau bahkan ratusan ribu siswa (dengan mendidik para guru dan teman sebaya yang kemudian, tanpa disadari, telah menyebarkan penyakit itu). Dan sekarang para siswa juga menulis tutorial di tempat untuk tutorial. Saya hanya ingin menangis di sudut. Situs pemrograman yang kompetitif seharusnya hanya memiliki regex untuk menolak header yang tidak standar .
Pasang kembali Monica
9

Dari N4606, Working Draft, Standar untuk Bahasa Pemrograman C ++:

17.6.1.2 Header [tajuk]

  1. Setiap elemen dari pustaka standar C ++ dideklarasikan atau didefinisikan (sebagaimana mestinya) di header.

  2. Pustaka standar C ++ menyediakan 61 header pustaka C ++, seperti yang ditunjukkan pada Tabel 14.

Tabel 14 - C ++ header header

<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>

Tidak ada <bits / stdc ++. H> di sana. Ini tidak mengejutkan, karena tajuk <bit / ...> adalah detail implementasi, dan biasanya membawa peringatan:

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

<bits / stdc ++. h> juga membawa peringatan:

*  This is an implementation file for a precompiled header.
Peluru peluru
sumber