Concepts / Using Standard Library Facilities Safely

Using Standard Library Facilities Safely

A program must #include the headers for the standard-library facilities it uses.

  • Programming

Why a Familiar Name Is Not Enough

Suppose you write a program and use the bare name vector, with no prefix and no declaration that brings it into scope. The name looks familiar, and you may have seen it in many other programs. The question is whether the program can use the standard library's vector facility simply because the name looks familiar. The answer depends on what the name must be connected to for the compiler to know what it refers to.

What do you think happens?

Can a program use the standard library's vector just by writing the bare name vector, if nothing else is written?

  • Yes, the name is familiar so the compiler knows what it means

  • No, the name must be connected to the header and to namespace std

Reveal answer
Answer:

No, the name must be connected to the header and to namespace std

The compiler can only identify a standard-library name when two things are in place. The program must include the header that describes the facility, and the name must be found in the namespace where the standard library defines it. A familiar-looking name satisfies neither requirement on its own.

This article covers two short reminders that work together. The first is that the program must include the header for each standard-library facility it uses. The second is that the facility's name must be reached in the namespace where the standard library defines it. Beginners often forget one of them, and the result is an error message that can look confusing at first. The sections below explain each reminder, show how they combine in a small program, and point out the most common ways they are missed.

The First Requirement: Including the Header

Definition

A header is the part of a library that the program needs to see before it uses a facility. The #include directive is how a program asks for that header to be brought into the file.

The rule is stated simply: if your program uses a facility, you should include the header for that facility. A program that uses cout should include the header that provides it, and a program that uses a string should include the header for strings. Each #include line in a file should match a facility the program actually depends on, so the file contains everything it needs.

cpp
Notes on the code
  • #include <iostream> brings in the header that describes the cout and endl facilities
  • std::cout names the cout facility inside namespace std
  • std::endl is also a standard-library facility and is qualified the same way
EASY

A habit that catches missing headers: after you write a program, read through it and ask, for each standard-library name you used, whether you have included the header that provides it. Try this on a program that uses cout and endl. Which header line would you check for?

Hints
  • Look at the names cout and endl, and identify the facility each one belongs to
  • The example earlier in this section used iostream for both names

The Second Requirement: Namespace std

Standard-library facilities are defined in namespace std. A namespace is a named region that groups names together, so the names of standard-library facilities live inside std rather than directly in the global namespace. The program therefore has to refer to each name in a way that reaches that namespace. The diagram below shows the relationship: the global namespace contains std, and std contains the names of the facilities the program uses.

Global namespacenamespace stdcoutstringvectorcontainscontainscontainscontains
Names such as cout, string, and vector sit inside namespace std, which itself sits within the global namespace. A bare name must be connected to std before the compiler can identify it.

There are two ways to make a name reach namespace std. The first is to write the std:: prefix in front of the name every time it is used. The second is to bring the name into scope with a using declaration, after which the bare name can be used. Either one satisfies the namespace reminder. The two methods do not change the header requirement, which still applies in both cases.

Tracing a Name Back to Its Requirements

The goal of this section is to follow a single standard-library name from the place where the program uses it back to the two things that make it available: the header and the namespace. The flowchart traces the steps the compiler follows when it reads cout. Each decision asks one of the two reminders, and a failure at any decision leads to an error rather than a resolved name.

cout used in codeWritten as std::cout?Search namespace stdHeader included?Name resolvedusing declarationpresent?Compile erroryesnoyesnoyesno
The compiler checks whether cout is qualified or brought in by a using declaration, then checks that the header is included. Only when both reminders hold does the name resolve.
Worked example

A program that uses a string and a vector correctly

Write a short program that prints a name stored in a string and the number of values stored in a vector. Include the headers for each facility and refer to each standard-library name correctly.

  1. 1
    List the facilities used

    The program uses cout and endl for output, string for the name, and vector for the list of values. Each of these belongs to a facility that needs its own header.

  2. 2
    Include a header for each facility

    The file includes iostream for cout and endl, string for the string type, and vector for the vector type. The header lines come before the code that uses them.

  3. 3
    Qualify each standard-library name

    Each use is written as std::string, std::vector, std::cout, or std::endl, so every name reaches namespace std.

  4. 4
    Check against both reminders

    Going through each name, the header is present and the namespace is reached. Both reminders hold for every name, so the program is prepared to use each facility.

Result

A program with three header lines and qualified names for every standard-library facility it uses.

cpp
Output
Ada has 3 scores
Notes on the code
  • Three header lines match the three facilities the program uses
  • std::string and std::vector are qualified with the namespace
  • std::cout and std::endl are qualified the same way as the rest

Correct and Incorrect Versions Side by Side

The two versions below use the same output statement. The first omits the header and the namespace qualification, so neither reminder is satisfied. The second includes the header and qualifies the names. Comparing them line by line shows exactly what each reminder contributes.

Before
int main() {
    cout << "Ready" << endl;
    return 0;
}

No header is included and the names are bare, so the compiler cannot connect cout or endl to the standard library.

After
#include <iostream>

int main() {
    std::cout << "Ready" << std::endl;
    return 0;
}

The header is included and each name is qualified with std::, so both reminders are satisfied.

No header#include <iostream>Bare coutstd::cout
The incorrect version lacks both the header and the namespace qualification. The correct version adds the header line and qualifies the names with std::.

Mistakes Beginners Make

  • Common mistake

    Assuming the header is unnecessary because the name is familiar

    What it looks like

    Using vector in a file that has no vector header line and expecting it to work because the name is widely known.

    Why it fails

    A familiar name does not tell the compiler which facility it refers to. The header makes the facility known to the file.

    Do this instead

    Include the header for each facility the program uses, such as vector for the vector facility.

  • Common mistake

    Including the header but leaving the name unqualified

    What it looks like

    Writing #include <iostream> and then cout << "Ready"; with no using declaration.

    Why it fails

    The header does not replace the namespace requirement. The bare name still has to be connected to namespace std.

    Do this instead

    Write std::cout, or add using std::cout; after the include.

  • Common mistake

    Qualifying the name but forgetting the header

    What it looks like

    Writing std::string name = "Ada"; without any string header line.

    Why it fails

    A qualified name does not replace the header. The file still needs the header that describes the facility.

    Do this instead

    Add #include <string> at the top of the file.

  • Common mistake

    Reading the error as a problem with the program logic

    What it looks like

    Looking for a bug in the output statement when the real problem is a missing header or missing qualification.

    Why it fails

    The error message can look confusing, so the cause is easy to misidentify.

    Do this instead

    Check the two reminders first: is the header included, and is the name reached in namespace std?

Checking a Program Before Running It

MEDIUM

The program below uses cout, endl, and string, but it is missing a header and at least one qualification. Find each problem, then rewrite the program so both reminders hold for every standard-library name.

int main() {
    string city = "Lagos";
    cout << city << endl;
    return 0;
}
Hints
  • Identify each standard-library name and the facility it belongs to, then check whether the file includes that facility's header
  • Check each name for the std:: prefix or a using declaration
  • The header for cout and endl is iostream, and the header for string is string
cpp
Output
Lagos
Notes on the code
  • The string header is added for the string facility
  • std::string and std::cout and std::endl each reach namespace std

Key Takeaways

  • A program must #include the header for each standard-library facility it uses, and a familiar-looking name does not replace that header
  • Standard-library facilities are defined in namespace std, so each name has to be reached in a way that reaches that namespace
  • The std:: prefix and a using declaration both satisfy the namespace reminder, and neither one replaces the header requirement
  • When a name fails, check both reminders: is the header included, and is the name qualified or brought into scope?

Related concepts

More concepts starting with U