Using std::setw() without <iomanip> header

588 Views Asked by At

How is it possible for this code to compile even though I didn't include <iomanip> ?

#include <iostream>
#include <fstream>

int main()
{
    std::cout << std::setw(5) << "test" << std::endl;
    return 0;
}

Compiles with:

clang++ test.cpp

But without <fstream> it throws the error:

test.cpp:5:20: error: no member named 'setw' in namespace 'std'
        std::cout << std::setw(5) << "test" << std::endl;
                     ~~~~~^
1 error generated.

On my friends Mac it throws error in both situations.

2

There are 2 best solutions below

0
utnapistim On BEST ANSWER

The headers include themselves internally, depending on the standard library implementation.

The standard doesn't guarantee that a symbol is undefined unless you include a certain file - instead it guarantees that a symbol will be defined if you do include it.

In this case, the fstream header includes code internally that happens to also have the definition of std::setw.

The code compiling on your compiler is a particularity of the implementation of your standard library.

In our current project, missing headers are one of the common causes of failed builds (build works on Windows but not on Mac, or the other way around).

As a rule, include the specified headers for everything you require in your code, even if the code compiles OK without the include.

0
MSalters On

Standard C++ headers may include other Standard headers, if that's convenient for the implementation. Your <fstream> as an implementation detail included <iomanip>, but on the Mac it apparently was not included.

Rule: Include what you need, and don't rely on accidental inclusion. This does not impose overhead; the standard headers can all be safely included more than once.