I posted a question with my code whose only #include
directive was the following:
#include <bits/stdc++.h>
My teacher told me to do this, but in the comments section I was informed that I shouldn't.
Why?
I posted a question with my code whose only #include
directive was the following:
#include <bits/stdc++.h>
My teacher told me to do this, but in the comments section I was informed that I shouldn't.
Why?
Including <bits/stdc++.h>
appears to be an increasingly common thing to see on Stack Overflow, perhaps something newly added to a national curriculum in the current academic year.
I imagine the advantages are vaguely given thus:
#include
line.Unfortunately, this is a lazy hack, naming a GCC internal header directly instead of individual standard headers like <string>
, <iostream>
and <vector>
. It ruins portability and fosters terrible habits.
The disadvantages include:
Don't do it!
More information:
Example of why Quora is bad:
#include <bits/stdc++.h>
and the difference in the size of the EXE file was 91 KB with, 89 KB without. –
Faust using namesapce std;
. Just two lines in and virtually every nice identifier is used. Incredibly frustrating to see it being taught. –
Hiller #include "stdafx.h"
–
Fryer using namespace std
makes me cringe more than the include. –
Elmer distance
, the word vector
certainly has no meaning outside of containers, … You're right a tool should help with this. But that's not a job for the compiler, that's the job of the IDE (and some of them indeed do it). –
Sarmiento Every single standard header must be parsed and compiled along with your source code, which is slow
. How slow? I did a quick "hello world" test and posted the results here. –
Sherasherar Why? Because it is used as if it were supposed to be a C++ standard header, but no standard mentions it. So your code is non-portable by construction. You won't find any documentation for it on cppreference. So it might as well not exist. It's a figment of someone's imagination :)
I have discovered - to my horror and disbelief - that there is a well-known tutorial site where every C++ example seems to include this header. The world is mad. That's the proof.
To anyone writing such "tutorials"
Please stop using this header. Forget about it. Don't propagate this insanity. If you're unwilling to understand why doing this is Wrong, take my word for it. I'm not OK being treated as a figure of authority on anything at all, and I'm probably full of it half the time, but I'll make an exception in this one case only. I claim that I know what I'm talking about here. Take me on my word. I implore you.
P.S. I can well imagine the abominable "teaching standard" where this wicked idea might have taken place, and the circumstances that led to it. Just because there seemed to be a practical need for it doesn't make it acceptable - not even in retrospect.
P.P.S. No, there was no practical need for it. There aren't that many C++ standard headers, and they are well documented. If you teach, you're doing your students a disservice by adding such "magic". Producing programmers with a magical mindset is the last thing we want. If you need to offer students a subset of C++ to make their life easier, just produce a handout with the short list of headers applicable to the course you teach, and with concise documentation for the library constructs you expect the students to use.
using namespace std;
. Then simple things like a user-defined gcd, swap or variable named data will act strangely or not compile at all, leaving the coder scratching their head as to what the issue could be. –
Exocentric There's a Stack Exchange site called Programming Puzzles & Code Golf. The programming puzzles on that site fit this definition of puzzle:
a toy, problem, or other contrivance designed to amuse by presenting difficulties to be solved by ingenuity or patient effort.
They are designed to amuse, and not in the way that a working programmer might be amused by a real-world problem encountered in their daily work.
Code Golf is "a type of recreational computer programming competition in which participants strive to achieve the shortest possible source code that implements a certain algorithm." In the answers on the PP&CG site, you'll see people specify the number of bytes in their answers. When they find a way to shave off a few bytes, they'll strike out the original number and record the new one.
As you might expect, code golfing rewards extreme programming language abuse. One-letter variable names. No whitespace. Creative use of library functions. Undocumented features. Nonstandard programming practices. Appalling hacks.
If a programmer submitted a pull request at work containing golf-style code, it would be rejected. Their co-workers would laugh at them. Their manager would drop by their desk for a chat. Even so, programmers amuse themselves by submitting answers to PP&CG.
What does this have to do with stdc++.h
? As others have pointed out, using it is lazy. It's non-portable, so you don't know if it will work on your compiler or the next version of your compiler. It fosters bad habits. It's non-standard, so your program's behavior may differ from what you expect. It may increase compile time and executable size.
These are all valid and correct objections. So why would anyone use this monstrosity?
It turns out that some people like programming puzzles without the code golf. They get together and compete at events like ACM-ICPC, Google Code Jam, and Facebook Hacker Cup, or on sites like Topcoder and Codeforces. Their rank is based on program correctness, execution speed, and how fast they submit a solution. To maximize execution speed, many participants use C++. To maximize coding speed, some of them use stdc++.h
.
Is this is a good idea? Let's check the list of disadvantages. Portability? It doesn't matter since these coding events use a specific compiler version that contestants know in advance. Standards compliance? Not relevant for a block of code whose useful life is less than one hour. Compile time and executable size? These aren't part of the contest's scoring rubric.
So we're left with bad habits. This is a valid objection. By using this header file, contestants are avoiding the chance to learn which standard header file defines the functionality they're using in their program. When they're writing real-world code (and not using stdc++.h
) they'll have to spend time looking up this information, which means they'll be less productive. That's the downside of practicing with stdc++.h
.
This raises the question of why it's worth taking part in competitive programming at all if it encourages bad habits like using stdc++.h
and violating other coding standards. One answer is that people do it for the same reason they post programs on PP&CG: some programmers find it enjoyable to use their coding skills in a game-like context.
So the question of whether to use stdc++.h
comes down to whether the coding speed benefits in a programming contest outweigh the bad habits that one might develop by using it.
This question asks: "Why should I not #include <bits/stdc++.h>
?" I realize that it was asked and answered to make a point, and the accepted answer is intended to be the One True Answer to this question. But the question isn't "Why should I not #include <bits/stdc++.h>
in production code?" Therefore, I think it's reasonable to consider other scenarios where the answer may be different.
#include <bits/stdc++.h>
or writing unreadable code) that the candidate would need to un-learn on the job. Having zero programming experience is also a red flag, but that's why we have interviews. –
Supporter bits/stdc++.h
only affects compilation speed and executable size, so it doesn't affect contest results. –
Supporter From N4606, Working Draft, Standard for Programming Language C++ :
17.6.1.2 Headers [headers]
Each element of the C++ standard library is declared or defined (as appropriate) in a header.
The C++ standard library provides 61 C++ library headers, as shown in Table 14.
Table 14 — C++ library headers
<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>
There's no <bits/stdc++.h> there. This is not surprising, since <bits/...> headers are implementation detail, and usually carry a warning:
- This is an internal header file, included by other library headers.
- Do not attempt to use it directly.
<bits/stdc++.h> also carries a warning:
- This is an implementation file for a precompiled header.
I at least like seeing a list of all headers one can include, and which version of C++ they pertain to, by looking at this header file. It is really useful in that regard.
<bits/stdc++.h>
, really?I wanted to see some real data--some numbers to compare compile time and binary executable size. So, here is a quick "hello world" comparison test.
Note: to learn where is the <bits/stdc++.h>
header file, and what is in it, jump straight down to the section at the bottom titled "Where and what is <bits/stdc++.h>
?".
Including the <bits/stdc++.h>
"include all headers" header is easy, but comparatively slow to compile.
Including the <bits/stdc++.h>
header file works fine with the GCC/g++ compiler (and presumably the LLVM Clang compiler too, since they aim to be GCC-compatible), and
Here is a sample C++ program:
// We will test including this header vs NOT including this header
#include <bits/stdc++.h>
#include <iostream> // For `std::cin`, `std::cout`, `std::endl`, etc.
int main()
{
printf("Hello ");
std::cout << "world!\n\n";
return 0;
}
Here are some build and run commands:
# make a bin directory
mkdir -p bin
# compile, timing how long it takes
time g++ -Wall -Wextra -Werror -O3 -std=c++17 include_bits_stdc++.cpp -o bin/a
# check binary executable size
size bin/a
# run
bin/a
#include <bits/stdc++.h>
at the topIf I run the "compile" command above with the code as-is, here are 10 compile times I see:
real 0m0.362s
real 0m0.372s
real 0m0.502s
real 0m0.383s
real 0m0.367s
real 0m0.283s
real 0m0.294s
real 0m0.281s
real 0m0.292s
real 0m0.276s
Average compile time: (0.362 + 0.372 + 0.502 + 0.383 + 0.367 + 0.283 + 0.294 + 0.281 + 0.292 + 0.276)/10
= 0.3412
seconds.
size bin/a
shows:
text data bss dec hex filename
2142 656 280 3078 c06 bin/a
#include <bits/stdc++.h>
at the top10 compile times:
real 0m1.398s
real 0m1.006s
real 0m0.952s
real 0m1.331s
real 0m1.549s
real 0m1.454s
real 0m1.417s
real 0m1.541s
real 0m1.546s
real 0m1.558s
Average compile time: (1.398 + 1.006 + 0.952 + 1.331 + 1.549 + 1.454 + 1.417 + 1.541 + 1.546 + 1.558)/10
= 1.3752
seconds.
size bin/a
shows:
text data bss dec hex filename
2142 656 280 3078 c06 bin/a
So, including the header works fine with the gcc/g++ compiler, and makes no difference on binary executable size, but it takes 1.3752 sec / 0.3412 sec = 4x longer to compile!
<bits/stdc++.h>
?The <bits/stdc++.h>
header file is included as part of the gcc/g++ compiler.
You can find it on your Linux (ex: Ubuntu) system with this command:
find /usr/include -ipath "*bits/stdc++.h*"
The above command is almost instant. But, if it doesn't find anything, you can search your entire file system like this, which will take much longer:
# Option 1: showing read permissions errors
find / -ipath "*bits/stdc++.h*"
# Option 2 (preferred): hiding read permissions (stderr, file descriptor 2)
# errors
find / -ipath "*bits/stdc++.h*" 2>/dev/null
If on Linux Ubuntu, <bits/stdc++.h>
will be located on your local system at:
/usr/include/x86_64-linux-gnu/c++/8/bits/stdc++.h
/usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h
You can view the file in the gcc source code directly online here: gcc/libstdc++-v3/include/precompiled/stdc++.h
I at least like seeing a list of all headers one can include, and which version of C++ they pertain to, by looking at that header file. It is really useful in that regard.
If you open the code above in an IDE with a great indexer, such as Eclipse (which has the best indexer I've ever found; it indexes far better than MS VSCode), and Ctrl + Click on the #include <bits/stdc++.h>
line, it will jump straight to that header file on your system! On Linux Ubuntu, it jumps straight to this path and opens this file: /usr/include/x86_64-linux-gnu/c++/8/bits/stdc++.h
.
You can view the latest version of this file in the gcc source code directly, here: gcc/libstdc++-v3/include/precompiled/stdc++.h. It is simply a header file which includes all other header files! This is really useful and insightful to just look at all header files in one place to get a feel for what they are and what they include! And again, in Eclipse, you can easily Ctrl + Click on each included header file to jump right to its source code implementation.
Here is the full, latest <bits/stdc++.h>
header file included with the gcc compiler. You can always copy and paste this content and create this file yourself if you want to include it in your own personal project or use it with another compiler.
gcc/libstdc++-v3/include/precompiled/stdc++.h:
// C++ includes used for precompiling -*- C++ -*-
// Copyright (C) 2003-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdc++.h
* This is an implementation file for a precompiled header.
*/
// 17.4.1.2 Headers
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <csetjmp>
#include <cstdarg>
#include <cstddef>
#include <cstdlib>
#if __cplusplus >= 201103L
#include <cstdint>
#endif
// C++
// #include <bitset>
// #include <complex>
#include <algorithm>
#include <bitset>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <numeric>
#include <typeinfo>
#include <utility>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <initializer_list>
#include <ratio>
#include <scoped_allocator>
#include <tuple>
#include <typeindex>
#include <type_traits>
#endif
#if __cplusplus >= 201402L
#endif
#if __cplusplus >= 201703L
#include <any>
// #include <execution>
#include <optional>
#include <variant>
#include <string_view>
#endif
#if __cplusplus >= 202002L
#include <bit>
#include <compare>
#include <concepts>
#include <numbers>
#include <ranges>
#include <span>
#include <source_location>
#include <version>
#endif
#if __cplusplus > 202002L
#include <expected>
#include <stdatomic.h>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#endif
#if _GLIBCXX_HOSTED
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cuchar>
#endif
// C++
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#if __cplusplus >= 201402L
#include <shared_mutex>
#endif
#if __cplusplus >= 201703L
#include <any>
#include <charconv>
// #include <execution>
#include <filesystem>
#include <optional>
#include <memory_resource>
#include <variant>
#endif
#if __cplusplus >= 202002L
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#include <format>
#include <latch>
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
#include <semaphore>
#include <source_location>
#include <syncstream>
#include <version>
#endif
#if __cplusplus > 202002L
#include <expected>
#include <generator>
#include <print>
#include <spanstream>
#if __has_include(<stacktrace>)
# include <stacktrace>
#endif
#include <stdatomic.h>
#include <stdfloat>
#endif
#if __cplusplus > 202302L
#include <text_encoding>
#endif
#endif // HOSTED
text
, data
, bss
, and dec
mean in the size
output:
The reason we do not use:
#include <bits/stdc++.h>
is because of effiency. Let me make an analogy: For those of you who know Java: If you asked your instructor if the following was a good idea, unless they are a bad instructor they would say no:
import java.*.*
The #include... thing does the same thing basically... That's not the only reason not to use it, but it is one of the major reasons not to use it. For a real life analogy: Imagine you had a library and you wanted to borrow a couple of books from the library, would you relocate the entire library next to your house?? It would be expensive and ineffiecient. If you only need 5 books, well then only take out 5... Not the whole library.....
#include <bits/stdc++.h>
Looks convienent to the program look I only need to type one include statement and it works, same thing with moving a whole library, look I only need to move one whole library instead of 5 books, one by one. Looks convienent to you that is, for the person who actually has to do the moving?? Not so much, and guess what in C++ the person doing the moving will be your computer... The computer will not enjoy moving the entire library for every source file you write :).....
import java.*.*
is valid and well-defined, in C++ #include <bits/stdc++.h>
IS NOT as that is, as that header even says, and internal header and an implementation-detail of GCC. It can change at any time, it could include macros that make your code format your drives, it could just vanish with the next release. –
Kimble If your teacher is an ICPC coach then he/she is right, but if your teacher is a software engineer probably he/she is not.
There are pros and cons of both:
pros:
cons:
As explained in the top answer to the Quora question mentioned by @Lightness Races in Orbit, there's nothing wrong with including bits/stdc++.h
in the context of a programming competition. The disadvantages around portability, compile time, and standardization are not relevant there. The same would be true in a college programming class if the example code uses that include.
If you're writing production code, then don't use it. It shouldn't be a big deal to switch back and forth depending on the purpose of the code you're currently writing.
#include <bits/stdc++.h>
are completely different things! –
Disarray <xlocale>
to GCC, you'll see what I mean. –
Sputter <xlocale>
will do nothing unless you rewrite GCC's <locale>
to use it. If you do, you'll get errors about not having files like <xlocinfo>
or <xdebug>
, and about not having MS's 20,000 or so internal macros defined. ...Not exactly the most trivial of things. ...Meanwhile, a third-party library can just be used as-is, perhaps with minor configuration necessary by defining one or two macros. There is a large difference between the two. –
Sputter #include <bits/stdc++.h>
is the Right Way. That's just how it's done in that community. In other contexts, they can be taught production programming standards. –
Supporter bits/stdc++.h
originates in the competitive programming community. See the Quora question linked in the top answer above. Competitive programming solutions are written once, and then thrown away once the contest is over. So the disadvantages cited above (portability, slow compilation, only works on one compiler, etc.) are not relevant. –
Supporter The biggest problem for me is that including this header file won’t compile. So if it’s there, I’ll have to remove it, try to compile, and add the standard header files that are needed.
My first thought would be that bits/stdc++.h
really seems to be a internal implementation detail header of GNU libstdc++. Thus, it should never be directly included from c++ program sources.
This is based on a consistent observation that on GNU/linux, subdirectories named bits
most likely seem to be the conventional place where the GNU libc and GNU libstdc++ put their internal private headers. Such headers contain implementation details, and their existence are not guaranteed to be stable across patch compiler versions.
Taking a look at the glibc headers directly located under /usr/include/x86_64-linux-gnu/bits/
, almost all of them prohibit direct inclusion by use of #error
directives.
Similarly, for the GNU libstdc++ headers; those are located under /usr/include/c++/12/bits/
or /usr/include/x86_64-linux-gnu/c++/12/bits/
(almost) all of them have documentation comments at the beginning such as:
/** @file bits/atomic_wait.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
Grepping under some bits
subdirectories seem to indicate this directory really is reserved for the implementation. Assuming version of gcc is 12, on a x86_64 arch, try the following commands:
$ grep "Never include" /usr/include/x86_64-linux-gnu/bits/*.h
$ grep "Do not attempt to use it directly" /usr/include/c++/12/bits/{*.h,*.tcc}
$ grep "Do not attempt to use it directly" /usr/include/x86_64-linux-gnu/c++/12/bits/*.h
Now, the header bits/stdc++.h
is somewhat special, as it is used to generate a precompiled header for the hole library. As such, it is more of a .cpp
implementation file rather than a proper .h
header file -- .cpp
source are not meant for inclusion.
Regarding the use of precompiled headers, good C++ practice is to make C++ programs/libraries that do not depend on whether a precompiled header is used to build the executable/library; simply adhere to the "Include what you use" principle. Use of a precompiled header should be specified by external means, from the build system or the command line, but not from #include
directives in source files.
From the viewpoint of the GNU libstdc++'s API, the file bits/stdc++.h
is not exposed as being part of it, and is only mentioned in the context of creating a binary pch
, and only gives instructions on how to use this precompiled header from the command line invocation of g++
, namely it does not instruct to directly include the file anywhere in source code; it is not exposed as being part of the public API of libstdc++'s header set -- in other words, it is not includeable (in essence).
© 2022 - 2024 — McMap. All rights reserved.
using namespace std;
out there somewhere. – Pozzybits/stdc++.h.gch
instead, the precompiled version. It exists because it has to exist so that the precompiled version of it can be generated. – Sotelo<bits/stdc++.h>
– Sverige