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

C++PortabilityTurbo C++C++ FaqImplementation Defined-Behavior

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

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:

Solution 2 - C++

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.

Solution 3 - C++

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.

Solution 4 - C++

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.

Solution 5 - C++

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

Solution 6 - C++

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

If on Linux, it will be located on your local system at /usr/include/x86_64-linux-gnu/c++/8/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-2022 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 <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 <algorithm>
#include <bitset>
#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 <string_view>
#include <variant>
#endif

#if __cplusplus >= 202002L
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#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 <spanstream>
#if __has_include(<stacktrace>)
# include <stacktrace>
#endif
#include <stdatomic.h>
#endif

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)

Solution 7 - C++

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.

Solution 8 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLightness Races in OrbitView Question on Stackoverflow
Solution 1 - C++Lightness Races in OrbitView Answer on Stackoverflow
Solution 2 - C++Kuba hasn't forgotten MonicaView Answer on Stackoverflow
Solution 3 - C++RedGreenCodeView Answer on Stackoverflow
Solution 4 - C++BulletmagnetView Answer on Stackoverflow
Solution 5 - C++Yunfei ChenView Answer on Stackoverflow
Solution 6 - C++Gabriel StaplesView Answer on Stackoverflow
Solution 7 - C++gnasher729View Answer on Stackoverflow
Solution 8 - C++RedGreenCodeView Answer on Stackoverflow