Some people claim that using namespace std; is bad practice. Others say it's OK in it's place. But everyone agrees that putting it in a header file is verboten.
So dear reader, who can explain this from Bjarne Stroustrup's own web site.
http://www.stroustrup.com/Programming/Graphics/std_lib_facilities.h
He didn't even put it at the top where you might notice it, its about 50 lines down.
What's going on here? Are mischievieous hackers out to discredit BS by putting bad code on his web-site?
Did you read the comment at the start of the file?
simple "Programming: Principles and Practice using C++" course header
to be used for the first few weeks. It provides the most common
standard headers (in the global namespace) and minimal exception/error
support.
Students: please don't try to understand the details of headers
just yet. All will be explained. This header is primarily used so that
you don't have to understand every concept all at once. Revised April
25, 2010: simple_error() added
The idea is so you can get started in the language without having to learn about namespaces day 1 nor worry about which standard headers need to be included for what.
Seeing as this is a course header, I think students are supposed to include it and then use most of the standard library that way. I am surprised Stroustrup teaches it that way (it is, in my opinion, still bad practice), but it does mean that he has one less bit of syntax to explain to his students. I don't think any non-coursework applications (or, even worse, libraries) are supposed to include it, so it's arguably somewhat acceptable.
I still think it's very poor style, and that saying that standard things have to be prefixed with std:: would have been better.
Firstly, that's teaching material and therefore far from the same. Secondly- so what? Everyone makes mistakes or maintains legacy headers. And thirdly, just because you invented a language doesn't make you the permanent master of everything- especially when there's a Standards committee.
Related
I have recently gotten into a project where the usage of header guards is forbidden as it is "bad design". Custom types are forward declared and headers are only included in cpp files.
This is the first project I have seen doing this and I find it quite uncomfortable to work with and if it were up to me I'd introduce the guards.
Using them has always been a given for me, so I don't even know how to argue against not using them other than highlighting the fact that it's uncomfortable. The project clearly compiles so in this case it's doable, but I'm left with a couple of questions:
Are there other scenarios where it would make the development impossible?
Does this style have a well-known benefit?
Are there known open source projects using this approach?
How would you convince the project leader to allow using guards?
I guess not including header in other header would cause maintaining list of headers in each translation unit (.cpp file).
If some dependency in one class on other is introduced, each header list is to be updated. Similarly, to take advantage of broken dependency, each list has to be updated too.
This does not look like a "good design".
Header guards are not "bad design". Refering to Bjarne Stroustrup and Herb Sutter:
SF.8: Use #include guards for all .h files
I would love to see the people behind your new project to argue with Stroustrup and Sutter over what is "bad design" in C++.
Forward declarations are a great tool, yes. But certainly not an answer to all situations. How would that work? You only have pointers as class members? You meticulously ensure nothing is defined in a header file?
I am working on compiling a very old piece of legacy code with g++ 4.4.7. All I really know about this code is that it was developed on a Irix/Sun system meaning it had a MIPS architecture. One rather odd thing I found when working with this code is that it sometimes calls function like endl and set_new_handler without the std:: prefix. Obviously this results in a compilation error. Since I am working under the assumption that this piece of code compiled on some machine at some time, I am a bit wary about blindly adding the std:: prefix to make it compile since It may change the behavior.
So, is there some old non-ISO compiler that allowed this piece of code to compile? Or is there some sort of flag that I can pass to gcc that would allow this piece of code to work?
The std namespace wasn't introduced into C++ until the first ISO/IEC standard in 1998 (often referred to as C++98). Prior to that time all of the standard library functions and objects were part of the global namespace.
Herb Sutter wrote a piece called Migrating to Namespaces in 2000 detailing his advice on making the transition.
I am not aware of any compiler flags that would fold the std namespace into the global one, and it would be a bad idea anyway - std is much larger today than when it was first introduced, and name collisions would be almost certain. See Why is “using namespace std” considered bad practice?
It is unlikely that you would have a collision with names that were part of the standard library prior to 1998, so it should be safe to pull those names individually into the global namespace. If you are using precompiled headers you can put the using directives in there after including the standard headers that define the symbols and fix the entire project silently. Just add a line for each compiler error you run across.
using std::endl;
using std::set_new_handler;
I would only advise this if your goal is to get the code up-and-running in as little time and effort as possible. The better long-term solution is still to put std:: in front of all the names from the library.
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. 😊
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.
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.
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.
Coming from a c# and java background, namespaces are nothing new to me and I have come to love the organizational structuring it brings to code.
I've been doing more work in c++ lately and I try to keep my coding habits as modern as possible. I have been toying around with some sandbox code, trying some new things and I would like to get some feedback on something I've been playing around with.
What I did was create a header file that explicitly declares a series of structured namespaces. The reason I did this is I wanted to layout a predefined structuring for namespaces to be used in the project. I realize that obviously the namespaces could be declared within any classes as the classes are defined but I like the idea of predefined structuring of the namespaces, such as (just an example):
namespace System
{
namespace IO
{
}
namespace Serialization
{
}
namespace Security
{
namespace Cryptography
{
}
}
}
etc. You get the idea.
My question is: Is there anything wrong with this approach? I figured it could be a good practice since it follows good coding practices with encapsulation and naming, etc.
I have seen some strange comments about similar things by old-school c++ devs, such as: "You're trying to combine Java and c++", or "Namespaces are just a way to mangle type names to avoid naming conflicts". I completely disagree with those opinions and don't feel those people are fully understanding the utility that namespaces can provide.
I don't think there's anything inherently "wrong" with it: you're documenting the intended structure of your namespaces.
But, ultimately, it's also pretty pointless, since nothing about this file stops namespaces with the same names from being [accidentally] created in a different structure, leaving you with a broken hierarchy there with actual types declared in it, and your intended hierarchy here with nothing at all in it.
Consequently I'd probably stick to standalone documentation for this sort of thing.
Declaring a namespace hierarchy in a header file is not very useful in practice; including the header file in any other files has no effect.
It seams to me you are trying to create a rule for people working on that project to follow, which or may or may not stick...it's all a matter of style and preference.
But there is nothing wrong with the approach it can do no harm.
In my project I use two libraries, v8 and boost. Boost uses the .hpp extension for its headers, while v8 uses the .h extension for its headers.
In the end of day, my source code starts like that:
#include "v8.h"
#include "boost/filesystem.hpp"
...
In other question I asked about this subject, the general answer was that it is okay, but I just should be consistent between names.
This code compiles well, but, coding styles/standards - is it okay? Is there any solution for this problem (like changing all .hpp to .h automatically somehow?)
Thanks. And sorry for those stupid questions.
Don't worry about the inconsistency, it doesn't matter. Too much time is often spent obsessing about such details, and everyone is guilty of it.
Just be consistent with your own coding standards.
You'll eventually use some 3rd party library or several that use different conventions than you. There's nothing you can do about it, and often 2 of those libraries you use will be conflicting with your standards and with each other. That's not only for include extensions, but also for naming convetions like function_that_does_something vs FunctionThatDoesSomthing .It's fine.
I would definitely strongly advice against trying to change someone else's library to fit into your coding standard. I.e. for example renaming boost .hpp to .h. This is a bad idea and when you want to upgrade to newer versions of the library it will be a nightmare.
Spend your time solving the problem you're solving in a more elegant way rather than worrying about details like this.
It's fine. Coding standards don't really come into it since you have to go with what you're given. If the v8 people only provide .h and the boost people only provide .hpp then, short of copying one set of files to the other choice or providing your own wrapper header files, you have few options.
Both of those option have their downsides for what is really dubious benefits, so I wouldn't concern yourself with the fact that you have to include two different file extensions.