Почему мне не следует #include ‹bits / stdc ++. H›?

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

#include <bits/stdc++.h>

Мой учитель сказал мне сделать это, но в разделе комментариев мне сказали, что я не должен.

Почему?


person Lightness Races in Orbit    schedule 04.08.2015    source источник
comment
Хм. Я должен был знать, что где-то есть включаемая версия using namespace std;.   -  person user4581301    schedule 05.08.2015
comment
почему этот заголовок вообще существует? конечно, ни один из стандартов не включает это, так как это принесет много мусора? и если он не включен ни в одну из публичных версий ... тогда почему он включен в дистрибутив?   -  person Chris Beck    schedule 01.02.2016
comment
@ChrisBeck: Это деталь реализации. Он не является частью общедоступного API и не предназначен для использования. Но его все равно нужно отправить, иначе ничего не получится. Стандарт включает, возможно, не использовать его по отдельности, но он существует для использования в предварительно скомпилированных заголовках. См. Комментарий вверху, в котором говорится: Это файл реализации для предварительно скомпилированного заголовка..   -  person Lightness Races in Orbit    schedule 01.02.2016
comment
@LightnessRacesinOrbit Если вы не должны использовать его самостоятельно, как его существование помогает в работе с PCH? Или gcc достаточно умен, чтобы автоматически переключаться на него для целей PCH при некоторых обстоятельствах?   -  person Daniel H    schedule 20.11.2017
comment
@DanielH: Хороший вопрос. Эм, я действительно не знаю, но, наверное, я так думал, да. Может быть, сам по себе хороший вопрос.   -  person Lightness Races in Orbit    schedule 20.11.2017
comment
@LightnessRacesinOrbit Он не является частью общедоступного API и не предназначен для использования. Совершенно неверно, он предназначен для общего использования в качестве предварительно скомпилированного заголовка. Libstdc ++ (pre) компилирует и устанавливает предварительно скомпилированную версию этого заголовка, поэтому, если вы включите ее, G ++ фактически будет включать bits/stdc++.h.gch, предварительно скомпилированную версию. Он существует, потому что должен существовать, чтобы можно было сгенерировать его предварительно скомпилированную версию.   -  person Jonathan Wakely    schedule 07.08.2019
comment
@JonathanWakely Я имею в виду общедоступный API стандартной библиотеки; не из libstdc ++. Люди, использующие его в Stack Overflow каждый день (и в своих проектах), не используют его по той причине или в случае использования, о котором вы говорите. Конечно, мой комментарий можно было бы сформулировать более точно, но обратите внимание, что я действительно указал на его использование для предварительно скомпилированных заголовков. Не стесняйтесь писать конкурирующий ответ.   -  person Lightness Races in Orbit    schedule 07.08.2019
comment
Geeksforgeeks распространяет это. В нем есть ответы на этапы программирования технических собеседований. Вот причина. Когда вы решаете проблему и пишете код, вы можете начать с вектора, но тогда вы думаете, что эта карта будет лучше. Поэтому каждый раз, когда вы передумаете, вам нужно обновлять заголовки. Это можно было пропустить в спешке. Так что здесь полезно. Однако при общем программировании использование не рекомендуется.   -  person Aditya Singh Rathore    schedule 20.04.2021


Ответы (5)


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

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

  • Вам нужно написать только одну #include строчку
  • Вам не нужно искать в каком стандартном заголовке все находится

К сожалению, это ленивый прием, который дает прямое имя внутреннему заголовку GCC вместо отдельных стандартных заголовков, таких как <string>, <iostream> и <vector>. Это портит портативность и порождает ужасные привычки.

К недостаткам можно отнести:

  • Вероятно, он будет работать только с этим компилятором
  • Вы не представляете, что он будет делать, когда вы его используете, потому что его содержимое не установлено стандартным
  • Даже простое обновление вашего компилятора до его собственной следующей версии может сломать вашу программу.
  • Каждый стандартный заголовок должен быть проанализирован и скомпилирован вместе с вашим исходным кодом, который работает медленно и приводит к громоздкому исполняемому файлу при определенных настройках компиляции.

Не делай этого!


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

Пример того, почему Quora плохая:

person Lightness Races in Orbit    schedule 04.08.2015
comment
возможно, что-то новенькое добавлено в национальную учебную программу в текущем учебном году Слепые ведут слепых :( - person Kuba hasn't forgotten Monica; 05.09.2015
comment
Однако при определенных настройках компиляции использование предварительно скомпилированных заголовков сокращает время компиляции. Кроме того, со стандартными готовыми настройками я просто скомпилировал тривиальную программу с #include <bits/stdc++.h> и без него, и разница в размере EXE-файла составила 91 КБ с файлом, 89 КБ без него. - person Evgeni Sergeev; 05.04.2016
comment
Просто пришла сюда через червоточину в другом вопросе, очень хорошо. Эту педагогическую привычку усугубляет то, что за ней обычно следует прямое using namesapce std;. Всего две строки и используются практически все красивые идентификаторы. Невероятно неприятно видеть, как этому учат. - person StoryTeller - Unslander Monica; 27.06.2017
comment
Что касается примера квора, он мог измениться со временем. Я посетил эту страницу сегодня и увидел как плюсы, так и минусы ‹bits / stdc ++. H›, где перечислены в конкретном контексте онлайн-соревнований по программированию. Я считаю их заключение нормальным. - person YSC; 06.02.2018
comment
Четвертый пункт полезен, если используются предварительно скомпилированные заголовки. См. здесь для объяснения, этот код в основном gcc версия #include "stdafx.h" - person M.M; 05.06.2018
comment
@ M.M: Не совсем - то, что вы предварительно компилируете заголовки, не означает, что вам нужно предварительно компилировать каждый заголовок - person Lightness Races in Orbit; 12.06.2018
comment
@EvgeniSergeev: 2KiB - это большой код, данные, символьная информация и т. Д. При попытке определить его эффект. Вы все понимаете, что добавляется? Для вашего компилятора? Текущий выпуск? Все выпуски между ними? Все будущие релизы? Если вам нужно выбрать между удобством и правильностью, есть только один допустимый вариант. - person IInspectable; 25.08.2018
comment
Надеюсь, это не учебная программа, а просто культ карго, распространенный на «конкурсных» сайтах или что-то в этом роде ... хотя, к сожалению, в любом случае меня ничто не удивит. - person underscore_d; 20.11.2018
comment
Не дай бог, вы используете с ним вариант предварительно скомпилированных заголовков. Взгляните на размер файла .pch, созданного VS в одном из ваших каталогов репозиториев / отладки (или выпуска). Он может составлять от десятков до сотен мегабайт. - person David C. Rankin; 04.08.2019
comment
Адвокат дьявола. Хотя все это, безусловно, верно для профессионального кода, вы можете возразить, что включение приемлемо для людей, впервые использующих C ++ для изучения программирования - это позволяет им сосредоточиться на собственном коде и упрощает работу учителя по оценке. Недостатки (за исключением, в некоторой степени, вашего второго пункта) исчезают в педагогической ситуации. Честно говоря, using namespace std заставляет меня съеживаться больше, чем включение. - person Spencer; 21.05.2020
comment
Давайте по-новому взглянем на это, пожалуйста. Все упомянутые выше пункты очень верны ... однако не следует ли нам исправить их все, чтобы на самом деле мы могли иметь только одну строку включения? Разве наш компилятор не должен делать всю работу, чтобы найти правильный заголовок и включить его, если мы захотим? - person Sujay Phadke; 24.06.2020
comment
Обновленная ссылка Стандарт C ++ - заголовки 16.5.1.2 - person David C. Rankin; 04.08.2020
comment
@SujayPhadke ›да, компилятор должен угадывать, что задумал разработчик. Поскольку, конечно, в мире существует только одна функция с именем distance, слово vector определенно не имеет значения вне контейнеров ... Вы правы, инструмент должен помочь с этим. Но это не работа компилятора, это работа IDE (и некоторые из них действительно это делают). - person spectras; 14.05.2021
comment
@spectras, не надо сарказма. Гадать не надо. По умолчанию компилятору просто нужно настроить значения по умолчанию. Если вы решите изменить его для своих целей, вы можете это сделать. Почему тысячи людей должны продолжать писать это для использования по умолчанию, когда один человек меняет поведение по умолчанию? - person Sujay Phadke; 26.05.2021
comment
@SujayPhadke находить вещи - это просто не работа компилятора. Если что-то не определено, это не определено. Просто, чисто, последовательно, надежно, воспроизводимо. Я согласен, автоматизация таких вещей - это здорово, и на самом деле многие IDE имеют эту функцию (бонус: она работает для всех библиотек, а не только для стандартной). Нет причин вносить несоответствия в язык и нарушать правила проектирования в цепочке инструментов. - person spectras; 26.05.2021

Почему? Потому что он используется так, как будто это должен быть стандартный заголовок C ++, но ни один стандарт не упоминает об этом. Таким образом, ваш код не является переносимым по конструкции. Вы не найдете никакой документации по нему на cppreference. Так что его с таким же успехом могло не быть. Это плод чьей-то фантазии :)

Я обнаружил - к своему ужасу и недоверию - что существует известный учебный сайт, где каждый пример C ++, кажется, включает этот заголовок. Мир сошел с ума. Это доказательство.


Всем, кто пишет такие "руководства"

Пожалуйста, прекратите использовать этот заголовок. Забудь об этом. Не пропагандируйте это безумие. Если вы не хотите понимать, почему это неправильно, поверьте мне на слово. Меня вообще не устраивают, когда меня рассматривают как авторитетную фигуру в чем-либо, и я, наверное, полон этого, но я сделаю исключение только в этом одном случае. Я утверждаю, что знаю, о чем здесь говорю. Поверьте мне на слово. Умоляю вас.

P.S. Я могу хорошо представить себе отвратительный «стандарт обучения», где могла возникнуть эта злая идея, и обстоятельства, которые к ней привели. Просто потому, что это казалось практической необходимостью, не делает это приемлемым - даже в ретроспективе.

P.P.S. Нет, практической необходимости в этом не было. Стандартных заголовков C ++ не так уж и много, и они хорошо документированы. Если вы преподаете, вы оказываете своим ученикам медвежью услугу, добавляя такое «волшебство». Воспитывать программистов с магическим складом ума - это последнее, чего мы хотим. Если вам нужно предложить студентам подмножество C ++, чтобы облегчить их жизнь, просто подготовьте раздаточный материал с кратким списком заголовков, применимых к курсу, который вы преподаете, и с краткой документацией по конструкциям библиотеки, которые, как вы ожидаете, студенты будут использовать.

person Kuba hasn't forgotten Monica    schedule 06.08.2015
comment
Это тот самый известный сайт, на котором каждый пример C ++ выглядит как программа на языке C? - person Surt; 20.12.2020
comment
Он говорит о GeeksForGeeks - person SuperNoob; 15.03.2021
comment
Будет весело, если этот заголовок будет включен вместе с using namespace std;. Затем простые вещи, такие как определяемый пользователем gcd, swap или переменная с именем data будет вести себя странно или вообще не компилироваться, заставляя кодировщика ломать голову над тем, в чем может быть проблема. - person PaulMcKenzie; 24.04.2021
comment
Я говорю о прототипе хорошо известного сайта. Их, к сожалению, очень много. И все они неизменно выглядят как слепые, ведущие слепого :( - person Kuba hasn't forgotten Monica; 26.04.2021

Есть сайт Stack Exchange под названием Программирование головоломок и кодового гольфа. Головоломки программирования на этом сайте соответствуют этому определению головоломки:

игрушка, проблема или другое приспособление, предназначенное для развлечения, представляя трудности, которые нужно решить изобретением или терпеливыми усилиями.

Они созданы для развлечения, а не для того, чтобы работающий программист мог развлечься реальной проблемой, с которой он сталкивается в своей повседневной работе.

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, сводится к тому, перевешивают ли преимущества скорости кодирования в соревнованиях по программированию вредные привычки, которые можно развить при ее использовании.

В этом вопросе задается вопрос: «Почему бы мне не включить #include <bits/stdc++.h>?» Я понимаю, что этот вопрос был задан, и на него был дан ответ, и принятый ответ призван стать Единым Истинным Ответом на этот вопрос. Но вопрос не в том, почему я не должен # включать <bits/stdc++.h> в производственный код? Поэтому я считаю разумным рассмотреть другие сценарии, в которых ответ может быть другим.

person RedGreenCode    schedule 23.04.2019
comment
Я уже проголосовал за, но, возможно, стоит отметить, что для развлечения - это хороший повод принять участие в соревновательном программировании. С другой стороны, произвести впечатление на потенциальных работодателей нельзя - это активно навредит вашему делу со мной. - person Martin Bonner supports Monica; 29.04.2019
comment
@MartinBonner Я знаю, что некоторые менеджеры по найму рассматривают опыт конкурентного программирования как красный флаг. Но пока ведущие компании-разработчики программного обеспечения используют задачи в стиле CP в своих собеседованиях и проводят конкурсы по программированию для поиска новых сотрудников, CP будет оставаться популярным среди начинающих разработчиков. - person RedGreenCode; 29.04.2019
comment
@RedGreenCode Я не менеджер (спасибо $ DEITY), но иногда я оказываю влияние на поиск сотрудников. И я определенно рассматриваю любое упоминание о соревновательном программировании как огромный красный флаг - не преимущества. - person Jesper Juhl; 23.07.2019
comment
@JesperJuhl Если технические интервьюеры в вашей компании используют алгоритмические головоломки в своих собеседованиях (как это делают многие), это дает кандидатам с опытом конкурентного программирования преимущество. Возможно, рациональным выбором для кандидатов является участие в CP, но избегайте упоминания об этом в своем резюме. - person RedGreenCode; 24.07.2019
comment
Хотя это правда, что этот заголовок может найти применение в некоторых соревнованиях по программированию, это не совсем то, откуда он взялся. Это пришло из класса. И тот, кто преподавал в этом классе, имел достаточно влияния, чтобы загрязнить - через последовавший за ним каскад - десятки, если не сотни тысяч учеников (обучая учителей и сверстников, которые тогда, невольно распространяли эту болезнь). И теперь эти студенты также пишут учебные пособия в месте, где можно найти учебные пособия. Я просто хочу плакать в углу. На сайтах соревновательного программирования должно быть просто регулярное выражение, чтобы отклонять любой нестандартный заголовок. - person Kuba hasn't forgotten Monica; 06.04.2020
comment
@RedGreenCode Почему соревновательное программирование - это красный флаг ?? Это лучше, чем тот, у кого нет опыта программирования .... - person Yunfei Chen; 08.07.2020
comment
@YunfeiChen Некоторые люди считают, что это поощряет вредные привычки (например, использование #include <bits/stdc++.h> или написание нечитаемого кода), от которых кандидату нужно будет отказаться на работе. Отсутствие опыта программирования - тоже красный флаг, но именно поэтому мы проводим собеседования. - person RedGreenCode; 08.07.2020
comment
@RedGreenCode Когда я говорю о нулевом опыте программирования, я имею в виду людей, которые никогда раньше не работали в сфере программирования, большинство выпускников университетов не работали в программировании раньше. Так что у них нет ничего, кроме диплома об ученой степени ... Хм, а почему соревнования по кодированию не заботятся об эффективности? Я думал, что в этом весь смысл соревнований ?? - person Yunfei Chen; 08.07.2020
comment
Результаты конкурса @YunfeiChen основаны на правильности, скорости выполнения и скорости кодирования (время отправки). Использование bits/stdc++.h влияет только на скорость компиляции и размер исполняемого файла, поэтому не влияет на результаты конкурса. - person RedGreenCode; 08.07.2020
comment
@YunfeiChen ›они также не заботятся (или даже не одобряют) многие вещи, которые очень важны для профессионального кода. Читаемость, возможность повторного использования, тестируемость (по частям), возможность опираться на существующие колеса, а не изобретать их заново,… - person spectras; 14.05.2021
comment
@spectras хорошо подходит для проверки достоверности, есть причина, по которой это называется кодированием гольфа, и все три из этих факторов очень субъективны, это не объективный показатель для их измерения, поэтому его не следует включать как часть критериев ... - person Yunfei Chen; 16.05.2021
comment
@MartinBonnersupportsMonica Мысль о том, что упоминание результатов CP в резюме - демонстрация соответствующих навыков решения проблем и активного энтузиазма - является негативом, просто безумие. Стиль кодирования и хорошее использование архитектуры, командной работы и т. Д. Имеют важное значение, но кандидату не нужно отмечать все эти поля в каждой точке резюме. - person Elliott; 16.06.2021

Из 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›. Это неудивительно, поскольку заголовки ‹bits / ...› представляют собой детали реализации и обычно содержат предупреждение:

*  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.
person Bulletmagnet    schedule 03.11.2019

Причина, по которой мы не используем:

#include <bits/stdc++.h>

это из-за эффективности. Позвольте мне провести аналогию: для тех из вас, кто знает Java: если вы спросите своего инструктора, было ли это хорошей идеей, они бы отказались, если только он не плохой инструктор:

import java.*.*

Элемент #include ... в основном делает то же самое ... Это не единственная причина не использовать его, но это одна из основных причин не использовать его. Для аналогии из реальной жизни: представьте, что у вас есть библиотека, и вы хотите взять в библиотеке пару книг. Не могли бы вы переместить всю библиотеку рядом с вашим домом? Это было бы дорого и неэффективно. Если тебе нужно всего 5 книг, то возьми только 5 ... Не всю библиотеку ...

#include <bits/stdc++.h>

Выглядит удобно для программы. Мне нужно ввести только один оператор include, и он работает, то же самое с перемещением всей библиотеки, послушайте, мне нужно перемещать только одну целую библиотеку вместо 5 книг, одну за другой. Выглядит удобно для вас, то есть для человека, который действительно должен делать переезд ?? Не так уж и много, и угадайте, что в C ++ человек, выполняющий перемещение, будет вашим компьютером ... Компьютеру не понравится перемещать всю библиотеку для каждого исходного файла, который вы пишете :) .....

person Yunfei Chen    schedule 08.07.2020