Why should I not #include <bits/stdc++.h>?

92.3k Views Asked by At

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?

10

There are 10 best solutions below

17
On BEST ANSWER

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:

  • You only need write one #include line.
  • You do not need to look up which standard header everything is in.

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:

  • It will probably only work on that compiler.
  • You have no idea what it'll do when you use it, because its contents are not set by a standard.
  • Even just upgrading your compiler to its own next version may break your program.
  • Every single standard header must be parsed and compiled along with your source code, which is slow and results in a bulky executable under certain compilation settings.

Don't do it!


More information:

Example of why Quora is bad:

4
On

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.

How bad is including <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>?".

Summary:

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

  1. makes no difference on binary executable size, but
  2. it takes up to 4x longer to compile!

My testing

Here is a sample C++ program:

include_bits_stdc++.cpp:

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

WithOUT #include <bits/stdc++.h> at the top

If 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

WITH #include <bits/stdc++.h> at the top

10 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

Conclusions

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!

Where and what is <bits/stdc++.h>?

Summary

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:

  1. On Ubuntu 18.04, with GCC 8: /usr/include/x86_64-linux-gnu/c++/8/bits/stdc++.h
  2. On Ubuntu 22.04, with GCC 11: /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.

Details

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

See also

  1. https://www.geeksforgeeks.org/bitsstdc-h-c/
  2. [my Questions & Answers] learn what text, data, bss, and dec mean in the size output:
    1. Electrical Engineering Stack Exchange: How do I find out at compile time how much of an STM32's Flash memory and dynamic memory (SRAM) is used up?
    2. Convert binutils size output from "sysv" format (size --format=sysv my_executable) to "berkeley" format (size --format=berkeley my_executable)
0
On

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.

4
On

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.

18
On

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.

0
On

From N4606, Working Draft, Standard for Programming Language C++ :

17.6.1.2 Headers [headers]

  1. Each element of the C++ standard library is declared or defined (as appropriate) in a header.

  2. 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.
12
On

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.

0
On

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:

  • Using it saves coding time
  • You don't need to take the pain of remembering which header contains what
  • If you have a source code limit(which ICPC style contests generally have) and you want to squeeze in as many lines as possible then it might come handy.

cons:

  • But it increases compile time.
  • Since it includes lots of namespaces, you may accidentally get into issues which might be hard to debug.
0
On

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

9
On

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 :).....