CS253: Software Development with C++

Spring 2021

Namespace Pollution

Show Lecture.NamespacePollution as a slide show.

CS253 Namespace Pollution

Guiding principles

An example

Consider the files in ~cs253/pub/Example/Pollution:

main.cc

#include "Graphics.h"
#include <string>

std::string fill = "gray";
std::string color = "red";

int main() {
    Graphics g(fill, color);
}

Fine—it defines a couple of strings, and initializes a Graphics object.

Graphics.h

#ifndef GRAPHICS_H_INCLUDED
#define GRAPHICS_H_INCLUDED

#include <string>
// 🦡 all over
using namespace std;

class Graphics {
  public:
    Graphics(const string &f, const string &p) : fill_color(f), pen(p) { }
  private:
    string fill_color, pen;
};

// Internal function to translate color name to int
int color(const string &name);

#endif /* GRAPHICS_H_INCLUDED */

It declares the class Graphics, and an auxillary function.

Try it out

% g++ -Wall ~cs253/Example/Pollution/main.cc .
/s/bach/a/class/cs253/Example/Pollution/main.cc:5:13: error: ‘std::__cxx11::string color’ redeclared as different kind of symbol
 std::string color = "red";
             ^~~~~
In file included from /s/bach/a/class/cs253/Example/Pollution/main.cc:1:
/s/bach/a/class/cs253/Example/Pollution/Graphics.h:16:5: note: previous declaration ‘int color(const string&)’
 int color(const string &name);
     ^~~~~
/s/bach/a/class/cs253/Example/Pollution/main.cc: In function ‘int main()’:
/s/bach/a/class/cs253/Example/Pollution/main.cc:8:16: error: reference to ‘fill’ is ambiguous
     Graphics g(fill, color);
                ^~~~
In file included from /usr/include/c++/8/bits/char_traits.h:39,
                 from /usr/include/c++/8/string:40,
                 from /s/bach/a/class/cs253/Example/Pollution/Graphics.h:4,
                 from /s/bach/a/class/cs253/Example/Pollution/main.cc:1:
/usr/include/c++/8/bits/stl_algobase.h:724:5: note: candidates are: ‘template<class _ForwardIterator, class _Tp> void std::fill(_ForwardIterator, _ForwardIterator, const _Tp&)’
     fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
     ^~~~
/s/bach/a/class/cs253/Example/Pollution/main.cc:4:13: note:                 ‘std::__cxx11::string fill’
 std::string fill = "gray";
             ^~~~

That didn’t go well

Alternative to using namespace std;

Alas, not having using namespace std; in a header file makes it more verbose:

class Graphics {
  public:
    Graphics(const std::string &fill, const std::string &color);
};

so do this, instead:

class Graphics {
    using string = std::string;
  public:
    Graphics(const string &fill, const string &color);
};

The alias is inside the class, so it doesn’t pollute the global namespace. The alias is in the private section of the class, so it’s not visible to users.

Don’t misunderstand