CS 70

Another Problem

  • LHS Cow speaking

    Header files are super useful, but there is still an issue that we need to address.

  • RHS Cow speaking

    Here's a simple example.

A Simple Example

constants.hpp:

constexpr double PI = 3.1415926535897932;

circles.cpp

#include "constants.hpp"
#include "constants.hpp"

double circumference(double radius) {
    return 2 * PI * radius;
}

double area(double radius) {
    return PI * radius * radius;
}

What will happen if we run clang++ -c circles.cpp?

Here's what I see when I run clang++ -c circles.cpp:

./constants.hpp:1:18: error: redefinition of 'PI'
constexpr double PI = 3.1415926535897932;
                ^
  • Cat speaking

    Sure, that makes sense. You aren't allowed to declare the same variable twice.

  • LHS Cow speaking

    Exactly! And when we #include "constants.hpp" twice, the declaration of PI is inserted twice.

  • Dog speaking

    Okay, got it! Don't #include the same file twice. Easy peasy!

  • LHS Cow speaking

    It's not as easy as it might seem. Let's change the example just a little bit.

A Slightly More Complicated Example

pi.hpp

constexpr double PI = 3.1415926535897932;

tau.hpp

#include "pi.hpp"

constexpr double TAU = 2*PI;

circles.cpp

#include "pi.hpp"
#include "tau.hpp"

double circumference(double radius) {
    return TAU * radius;
}

double area(double radius) {
    return PI * radius * radius;
}

What will happen if we run clang++ -c circles.cpp?

Here's what I see when I compile our code:

In file included from circles2.cpp:2:
In file included from ./tau.hpp:1:
./pi.hpp:1:18: error: redefinition of 'PI'
constexpr double PI = 3.1415926535897932;
                 ^
  • RHS Cow speaking

    Do you see what happened?

  • Cat speaking

    Yeah, so tau.hpp included pi.hpp, but circles.cpp included both pi.hpp and tau.hpp, so PI still got declared twice.

  • LHS Cow speaking

    Yes, exactly!

  • Duck speaking

    I could have just avoided it by putting them both in the same file.

  • LHS Cow speaking

    Sure, this time. But it can get worse than that. You can have a file that includes a file that includes a file that includes a file and another file that includes a file that includes a file that includes the same file!

  • RHS Cow speaking

    Clearly we need a way to #include files when we need to but also protect ourselves from multiple declarations!

(When logged in, completion status appears here.)