Reputation: 53
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. 😊
Upvotes: 3
Views: 147
Reputation: 33932
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.
Upvotes: 2
Reputation: 2689
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.
Upvotes: 1
Reputation: 822
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.
Upvotes: 1