Чому я не повинен #include <bits / stdc ++. H>?


267

Я розмістив запитання зі своїм кодом, єдиною #includeдирективою якого було таке:

#include <bits/stdc++.h>

Мій вчитель сказав мені це зробити, але в розділі коментарів мені повідомили, що я не повинен.

Чому?


72
Ага. Я мав би знати, що там буде using namespace std;десь версія .
user4581301

1
чому цей заголовок навіть існує? напевно, жоден із стандартів не включає насправді це, оскільки це принесе багато сміття? і якщо його не включено жодною з громадськості, то ... чому він постачається в дистрибутиві?
Кріс Бек

10
@ChrisBeck: це детальна інформація про реалізацію. Він не є частиною "загальнодоступного API" або призначений для використання. Але його все одно потрібно відправляти, інакше нічого не вийде. Цей стандарт може не використовувати його окремо, але він є для використання у попередньо складених заголовках. Дивіться коментар у верхній частині, який говорить: "Це файл реалізації попередньо складеного заголовка". .
Гонки легкості на орбіті

1
@LightnessRacesinOrbit Якщо ви не повинні використовувати його самостійно, як допомагає його існування проти PCH? Або gcc досить розумний, щоб автоматично переключитися на нього для цілей PCH за деяких обставин?
Даніель Н

2
@LightnessRacesinOrbit "Це не частина" загальнодоступного API "або призначена для використання." Зовсім неправильно, він призначений для громадського використання, як попередньо складений заголовок. Libstdc ++ (попередньо) компілює та встановлює попередньо скомпільовану версію цього заголовка, тому, якщо ви включите його, тоді G ++ буде фактично включати bits/stdc++.h.gchзамість цього попередньо компільовану версію. Він існує тому, що він повинен існувати, щоб можна було сформувати попередньо складену версію.
Джонатан

Відповіді:


310

Включення, як <bits/stdc++.h>видається, стає все більш поширеним, що можна побачити на стеці Overflow, можливо, щось, що нещодавно додано до національної навчальної програми у поточному навчальному році

Я думаю, що переваги розпливчасто даються таким чином:

  • Вам потрібно написати лише один #includeрядок
  • Не потрібно шукати, у якому стандартному заголовку все є

На жаль, це ледачий хак, називаючи ПКУ внутрішній заголовок безпосередньо замість окремих стандартних заголовків , як <string>, <iostream>і <vector>. Це руйнує портативність і виховує жахливі звички.

До недоліків можна віднести:

  • Можливо, він буде працювати лише над цим компілятором
  • Ви не маєте поняття, що він буде робити, коли ви його використовуєте, оскільки його вміст не встановлений стандартом
  • Навіть просто оновлення компілятора до наступної версії може зламати вашу програму
  • Кожен стандартний заголовок повинен бути проаналізований та скомпільований разом із вихідним кодом, який є повільним і призводить до об'ємного виконання у певних налаштуваннях компіляції

Не робіть цього!


Більше інформації:

Приклад того, чому Quora поганий:


77
"можливо, щось щойно додане до національної навчальної програми в поточному навчальному році" Сліпий веде сліпих :(
Поновіть Моніку

14
@KubaOber: Саме так.
Гонки легкості по орбіті

31
Щойно прийшов сюди через червоточину в іншому питанні, дуже добре. Що робить цю звичку викладання гіршою, що вона, як правило, супроводжується прямим using namesapce std;. Всього використовується два рядки і практично кожен приємний ідентифікатор. Неймовірно засмучує бачити, як його навчають.
StoryTeller - Невідповідна Моніка

6
На прикладі квори це, можливо, змінилося з часом. Я сьогодні відвідав сторінку, і плюси і мінуси <bits / stdc ++. H>, де вказано в конкретному контексті онлайн-конкурсів програмування. Я вважаю їх висновок нормальним.
YSC

3
@EvgeniSergeev: 2KiB - це багато коду, даних, інформації про символи тощо, коли намагаються визначити її ефект. Ви розумієте все, що додається? Для вашого компілятора? Поточний реліз? Усі випуски між ними? Усі майбутні випуски? Якщо вам потрібно визначитися між зручністю та правильністю, є лише один дійсний варіант.
Неочікувана

47

Чому? Тому що він використовується так, як ніби це був стандартний заголовок C ++, але жоден стандарт не згадує його. Тож ваш код не є портативним за конструкцією. Ви не знайдете жодної документації на це на cppreference . Тож воно може і не існувати. Це плід чиєїсь фантазії :)

Я виявив - на моє жах і невіру - що існує добре відомий сайт підручника, де кожен приклад C ++, здається, містить цей заголовок . Світ божевільний. Це доказ.


Для всіх, хто пише такі "підручники"

Будь ласка, перестаньте використовувати цей заголовок. Забути про це. Не поширюйте це божевілля. Якщо ви не бажаєте розуміти, чому це робиться Неправильно , прийміть моє слово. Мені не вдається взагалі трактуватись як фігуру авторитету, і я, мабуть, наполовину наповнений цим, але я буду робити виняток лише в цьому випадку. Я стверджую, що я знаю, про що тут говорю. Прийміть мене до свого слова. Я благаю вас.

PS Я добре уявляю той мерзотний "навчальний стандарт", де могла відбутися ця зла ідея, та обставини, що призвели до неї. Просто тому, що, здавалося, є практична потреба, це не робить його прийнятним - навіть не в ретроспективі.

PPS Ні, практичної потреби в цьому не було. Стандартних заголовків C ++ не так багато, і вони добре задокументовані. Якщо ви викладаєте, ви робите своїм учням сумлінну послугу, додаючи таку "магію". Підготовка програмістів з магічним мисленням - це останнє, що ми хочемо. Якщо вам потрібно запропонувати студентам підмножину C ++, щоб полегшити їхнє життя, просто складіть роздатковий матеріал із коротким списком заголовків, що застосовуються до курсу викладання, та зі стислим документом для бібліотечних конструкцій, які ви очікуєте від студентів.


35

Існує сайт обміну стеками під назвою Puzzle Puzzle & Code Golf . В головоломки програмування на цьому сайті відповідають цьому визначенню головоломки :

іграшка, проблема чи інший привід, розроблений для розваги, представляючи труднощі, що вирішуються винахідливістю або зусиллями пацієнта.

Вони створені для розваги, а не для того, щоб працюючий програміст міг розвеселити проблему в реальному світі, що виникає в їхній щоденній роботі.

Code Golf - це "різновид змагань з комп’ютерного програмування для відпочинку, в яких учасники прагнуть досягти якомога коротшого вихідного коду, який реалізує певний алгоритм". У відповідях на сайті PP&CG ви побачите, що люди вказують кількість байтів у своїх відповідях. Коли вони знайдуть спосіб відголити кілька байтів, вони викреслять оригінальне число і записують нове.

Як ви могли очікувати, гольф з кодом винагороджує екстремальне зловживання мовою програмування. Одно буквені назви змінних. Немає пробілів. Творче використання функцій бібліотеки. Незадокументовані функції. Нестандартні практики програмування. Жахливі хаки.

Якщо програміст подав запит на тягу на роботі, що містить код у стилі гольфу, його буде відхилено. Їхні колеги сміялися б над ними. Їхній менеджер завітав за їхній стіл для чату. Незважаючи на це, програмісти розважають себе, надсилаючи відповіді на PP&CG.

Що це стосується stdc++.h? Як зазначали інші, користуватися ним ліниво. Він не портативний, тому ви не знаєте, чи він працюватиме на вашому компіляторі чи наступній версії компілятора. Це виховує шкідливі звички. Це нестандартно, тому поведінка вашої програми може відрізнятися від очікуваного. Це може збільшити час компіляції та розмір виконуваного файлу.

Це все дійсні та правильні заперечення. То чому б хтось використовував цю чудовисько?

Виявляється, деяким люблять програмування пазлів без коду гольфу . Вони збираються та змагаються на таких заходах, як ACM-ICPC, Google Code Jam та Facebook Hacker Cup, або на таких сайтах, як Topcoder та Codeforces. Їх ранг ґрунтується на коректності програми, швидкості виконання та швидкості подання рішення. Для максимальної швидкості виконання багато учасників використовують C ++. Для досягнення максимальної швидкості кодування деякі з них використовують stdc++.h.

Це гарна ідея? Давайте перевіримо список недоліків. Переносність? Не має значення, оскільки для цих подій кодування використовується певна версія компілятора, про яку учасники знають заздалегідь. Відповідність стандартам? Не стосується блоку коду, термін корисного використання якого становить менше однієї години. Час компіляції та розмір виконуваного файлу? Вони не є частиною конкурсної статті.

Тож ми залишилися зі шкідливими звичками. Це дійсне заперечення. Використовуючи цей заголовок, учасники уникають шансів дізнатися, який стандартний файл заголовка визначає функціонал, який вони використовують у своїй програмі. Коли вони пишуть код у реальному світі (а не використовують stdc++.h), їм доведеться витрачати час на пошук цієї інформації, а це означає, що вони будуть менш продуктивними. Це і є недоліком практики stdc++.h.

Це викликає питання, чому варто взагалі брати участь у конкурентному програмуванні, якщо це заохочує шкідливі звички, як використання stdc++.hта порушення інших стандартів кодування. Одна з відповідей полягає в тому, що люди роблять це з тієї ж причини, коли вони розміщують програми на PP&CG: деяким програмістам приємно використовувати свої навички кодування в ігровому контексті.

Тож питання про те, чи потрібно використовувати, stdc++.hзводиться до того, чи переваги швидкості кодування в конкурсі програмування переважають шкідливі звички, які можна розвинути, використовуючи його.

Це запитання задає: "Чому я не # включаю <bits/stdc++.h>?" Я розумію, що його попросили і відповіли, щоб зробити точку, і прийнята відповідь має на меті бути Єдиним істинним відповіддю на це питання. Але питання не в тому, "чому я не повинен # включати <bits/stdc++.h>у виробничий код?" Тому я вважаю, що розумно розглянути інші сценарії, де відповідь може бути різною.


5
Я вже відмовився, але, можливо, варто зазначити, що "для розваги" - це вагомий привід взяти участь у конкурентному програмуванні. З іншого боку, "справити враження на потенційних роботодавців" немає - це активно зашкодить вашій справі зі мною.
Мартін Боннер підтримує Моніку

2
@MartinBonner Я знаю, що деякі менеджери з найму бачать досвід конкурентного програмування червоним прапором. Але поки провідні програмні компанії використовують проблеми зі стилем CP у своїх інтерв'ю та проводять конкурси програмування, щоб знайти нових рекрутів, CP продовжить користуватися популярністю серед прагнучих розробників.
RedGreenCode

@RedGreenCode Я не менеджер (дякую $ DEITY), але інколи маю вплив на прокат роботи. І я точно бачу будь-яке посилання на «конкурентне програмування» як величезний червоний прапор - не перевага.
Jesper Juhl

3
@JesperJuhl Якщо технічні інтерв'юери вашої компанії використовують алгоритмічні головоломки у своїх інтерв'ю (як і багато хто), це дає перевагу кандидатам, які мають досвід конкурентного програмування. Можливо, раціональним вибором для кандидатів є участь у КП, але уникайте згадування про це у своєму резюме / резюме.
RedGreenCode

2
Хоча це правда, що цей заголовок може знайти застосування в конкурентному програмуванні, але не зовсім звідки він узятий. Походив із класної кімнати. І той, хто викладав у цьому класі, мав достатній вплив, щоб забруднити - через каскад, який слідував за цим - десятки, якщо не сотні тисяч учнів (навчаючи вчителів та однолітків, які тоді мимоволі поширювали цю хворобу). І тепер ці студенти також пишуть підручники у навчальному посібнику. Я просто хочу плакати в кутку. На сайтах конкурентоспроможного програмування просто повинен бути регулярний вираз для відхилення будь-якого нестандартного заголовка .
Відновіть Моніку

8

Від N4606, Робочий проект, Стандарт для мови програмування C ++:

17.6.1.2 Заголовки [заголовки]

  1. Кожен елемент стандартної бібліотеки C ++ оголошується або визначається (у відповідних випадках) у заголовку.

  2. Стандартна бібліотека C ++ містить 61 заголовки бібліотеки C ++, як показано в таблиці 14.

Таблиця 14 - заголовки бібліотеки 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>

Там немає <bits / stdc ++. H>. Це не дивно, оскільки <біт / ...> заголовки є деталізацією реалізації, і зазвичай містять попередження:

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

<bits / stdc ++. h> також містить попередження:

*  This is an implementation file for a precompiled header.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.