3

Very new to programming and have some questions about headers.

In the book it uses:

#include "std_lib_facilities.h"

My teacher always uses:

#include <iostream>
using namespace std;

Any reason why we would use one over another? One work better than the other? Any help would be appreciated.

  • 3
    excellent question, so good, it's been answered.. http://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename – Stanton Sep 15 '15 at 22:50
  • @Stanton Um, how does that answer this question? – T.C. Sep 15 '15 at 22:54
  • Your teacher is following some pretty poor practices, unless he/she explains the implications of `using namespace std;` and restricts it to a very limited scope. – juanchopanza Sep 15 '15 at 23:05
  • 1
    @Stanton can you please explain how this answers the question? – Warren McAllister Sep 15 '15 at 23:20
  • So, the question is not what stanton posted. I am literally asking what the difference is with them. I'm that new. Looks like @JArkinstall gave the answer I was looking for. – Warren McAllister Sep 16 '15 at 01:01

3 Answers3

2

The headers included in a file change from file to file based on the needs of the file. What Stroustrup uses works in the context of his source examples. What your teacher uses matches the teacher's needs.

What you use will depend on your needs and the needs of the program.

Each file should contain all of the headers required to be complete and no more. If you use std::string in the file, #include <string>. If you use std::set, #include <set>.

It may appear to be unnecessary to include some header files because another include includes them. For example since iostream already includes string, why bother including both iostream and string? Practically it may not matter, string was included, but it is now a maintenance issue. Not all implementations of a given header will have the same includes. You will find yourself in interesting cases where the code compiles in one compiler, or version of the compiler, and not another because an include dependency changed in a header possibly two or three includes down the chain.

It is best to head that off for you and everyone who may follow in maintaining your code.

If you are not concerned about maintenance, look up the y2k bug. That was a problem because software written to meet the needs and constraints of the 1960's and 1970's was still being used 40 years later in a world with different needs and vastly different constraints. You'd be surprised how much code outlives the expected lifetime.

While it's nice to have certain employment for the rest of your life, it sucks to blow a weekend of your Hawai'i vacation because the modification to your that could have been done by a co-op turned into a nightmare because GCC 7.12 is just plain different from the GCC 5.2 under which you originally wrote the program.

You will also find that as long chains of files get included, a poorly constructed header can inject ordering dependencies on headers. Program X works fine if header Y is included before header Z. This is because Z needs stuff included by Y that Z did not declare. Don't be the person to write Z.

However, don't include everything. The more you include, the longer it takes to compile and the more exposure you have to unforeseen combinations reacting badly. Like it or not, someone always writes header Z, and you don't want the kick to the schedule debugging Z causes if you don't to include Z.

Why does it take longer to compile? Think of each include as a command for the compiler (preprocessor, really) to paste the included file into the including file. The compiler then compiles the combined file. Every include needs to be loaded from disk (slow), possibly security scanned (often awesomely slow), and merged into the file to be compiled (faster than you might expect). All of the included file's includes are pasted in, and before you know it, you have one huge mother of a file to be parsed by the compiler. If a huge portion of that huge file is not required, that's wasted effort.

Avoid like the plague structures that require header Y including header Z and header Z including Y. An include guard, more on that later, will protect the obvious recursion problem (Y includes Z includes Y includes Z includes...), but also ensures that you cannot include either Y or Z in time to satisfy Z or Y.

Some common headers, string is a favourite, are included over and over again. You don't want to keep re including the header and its dependencies, but you also want to make sure it has been included if it hasn't. To solve this problem you surround your headers with a Header guard. This looks like:

#ifndef UNIQUE_NAME 
#define UNIQUE_NAME
// header contents goes here
#endif

If UNIQUE_NAME has not been defined, define it and replicate the header contents in the file to be compiled. This has a couple problems. If UNIQUE_NAME is not unique, you're going to have some really freaky error "not found" messages because the first header guard will block the include of the next.

The uniqueness problem is solved with #pragma once, but #pragma once has a few problems of it's own. It's not standard C++ so it is not implemented in all compilers. #pragma instructions are silently ignored (unless compiler warnings are turned way up and sometimes not even then) if the pragma is not supported by the compiler. Utter chaos ensues as headers are repeatedly included and you'll have warning. #pragma once can also be fooled by complicated directory structures including network maps and links.

So... Stroustrup is using #include "std_lib_facilities.h" because it includes all of the bits and pieces he needs for the early lessons in his book without having to risk information overload by covering the nitty-gritty of those bits and pieces. It's classic chicken and egg. Stroustrup wants to teach those early lessons in a controlled manner by reducing the information load on the student until Stroustrup can cover the material required to actually understand the background details of those early lessons.

Great teaching strategy. In a way, the strategy is worth emulating in code: He's eliminated a problem by adding a layer of indirection.

But it can be a bad strategy in the programmer's real world of sliding ship dates, pointy-haired bosses, death marches, and lawsuits. You don't want to waste time fixing a non problem that didn't need to be there in the first place. Code that's not there has no bugs. Or is a bug, but that's another issue.

And Bjarne Stroustrup can get away with some stuff because he's Bjarne expletive deleted Stroustrup. He knows what he's doing. He's demonstrated that. He's probably considered, measured, and weighed the implications of his megaheader because he knows what they are. If he was worried that something in it was going to smurf over his students, he wouldn't have done it.

The first year programming student isn't Bjarne Stroustrup. Even if they have a brain the size of a planet, they lack the years of experience. It's usually the the stuff you don't know that you have to worry about, and Stroustrup's pool of "don't know" is going to be notably smaller.

There are all sorts of unsafe things that you can do when you know what you are doing and can honestly justify the doing. And as long as you take into account that you might not be the only person with a vested interest in the code. Your super-elegant-but-super-arcane solution isn't much if the coder who picks up your portfolio after you get hit by a bus can't read it. Your lovely code is going into the bin and your legacy will be, "What the smurf was that smurfing idiot trying to do with that smurf?" At the very least leave some notes.

Stroustrup also has page and word constraints that require him to compress the text in the printed edition. One Header to Rule Them All helps dramatically.

Your teacher has a similar problem with student overload, but probably doesn't have the print space constraints. For the snippets of code you've seen so far, all that has been required is the basic input and output that requires iostream. And probably string, but even I'll admit it'll be really hard to write the iostream header without it including string.

Soon you will start seeing #include <vector>, #include <fstream>, and #include<random>, as well as start writing your own headers.

Strive to learn to do it right, otherwise you have a nasty software engineering learning curve after graduation.

user4581301
  • 33,082
  • 7
  • 33
  • 54
1

The include_std_facilities.h file, supplied with the books or accessible online, is like a shortcut to including multiple header files (if you include that file, looking at the source, it just includes some useful headers like so that you don't need to explicitly include them yourself).

Think of it as inviting your mother around to dinner. You invite her, and that inevitably implies that your dad (okay Im making assumptions), your sister and that annoying yappy dog of hers will automatically come for dinner too, without asking them explicitly.

It's not really a great practise, but I presume the author has their reasons.

Your teacher is correct, the minimal code will often include iostream so that you can output to the terminal. However, and this is something I have to stress, using namespace std is bad practice. You can access std functionality by explicitly using std:: - for example:

std::cout << "hello world!" << std::endl;

Working outside of the std namespace is beneficial for a multitude of reasons. You can find these by a bit of googling.

Jake
  • 822
  • 5
  • 14
  • 1
    Please stop spreading the [falsehood](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice/26722134#26722134) that using `using namespace std;` is bad practice. "The author" in this case btw is Bjarne Stroustrup, best known as the *inventor* of C++ and if `using namespace std` is good enough for him... – mattnewport Sep 15 '15 at 23:03
  • 3
    The recommendation for using the standard namespace was from the teacher, not Stroustrup. It certainly isn't a falsehood - namespacing projects appropriately is important, and learning the habit of using the standard namespace in code from an early stage leads to an unnecessary learning curve later on in the learning process. Is it not better just to learn where things exist and how to access them without learning a shortcut which is not appropriate in most real-world situations? – Jake Sep 15 '15 at 23:12
  • @mattnewport you are exactly right. Book is by bjarne stroustrup. – Warren McAllister Sep 15 '15 at 23:13
  • If you look at the [std_lib_facilities.h header](http://www.stroustrup.com/Programming/std_lib_facilities.h) it is from a book by Bjarne Stroustrup and it has `using namespace std;` in it. – mattnewport Sep 15 '15 at 23:13
  • 2
    Maybe so. My point is that it adds an unnecessary learning curve later on. It depends on your group guidelines, I suppose - but I've had the misfortune of working on legacy codebases which have very different ideas of what a vector should be. – Jake Sep 15 '15 at 23:20
  • 3
    @mattnewport It is most definitely poor practice. You should see the number of questions that turn up here that are hard to diagnosed because somebody has foolishly said `using namespace std;` in their code. It is, almost always, a *terrible* idea. – juanchopanza Sep 15 '15 at 23:23
  • 1
    @JArkinstall it is usually not appropriate to use it in a header. It is usually fine to use it in a .cpp file. That's the advice Herb Sutter and Andrei Alexandrescu give in *C++ Coding Standards* and it's the [advice I believe is correct](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice/26722134#26722134) in most circumstances. – mattnewport Sep 15 '15 at 23:25
  • 3
    @mattnewport I have to disagree. I have spent too much time helping fix bugs caused by that. Much easier to reject at code review stage and move on. I guess *usually* fine is not good enough for me. – juanchopanza Sep 15 '15 at 23:28
  • @JArkinstall You could also mention that you can use using declarations, which can also be used inside scopes (e.g. `using std::cout;`, `using std::vector;` etc.) – juanchopanza Sep 15 '15 at 23:38
1

My guess is the author of the book does it to keep the code examples shorter, not as an example of exemplary style. No need to put boiler plate text in every example.

For my take, putting a bunch of includes into a header file that everybody includes (that isn't a precompiled header) can slow compilation down considerably (not only having to seek and load each file, but to check dependencies, etc), particularly if you have an overzealous IT department that insists on live scanning every file access.

Russ Schultz
  • 2,545
  • 20
  • 22