Skip to Content
Course content

20: Using Directives and Declarations

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've noticed a recurring pattern with developers moving to C++ from languages like Python or Java. They treat the #include directive as if it's a smart "import" statement. They assume that when they write #include "player.h", the compiler is intelligently linking a module or importing a namespace. It feels like a high-level operation, but in reality, it's much more primitive—and that's exactly where the bugs start to creep in.

The Myth: #include "Imports" a Library

Let's look at a concrete example of how this misunderstanding breaks your build. Imagine you're building a small game engine. You create a header file called game_settings.h to hold a global variable for the gravity constant:

// game_settings.h
int gravity = -9.81; 

Now, you include this header in two different files: physics.cpp and main.cpp. Everything looks fine in your editor, but the moment you hit compile, the linker screams at you with a "multiple definition of 'gravity'" error. You'll be confused because you only wrote the variable once in the header. You thought you were "importing" the setting, but you weren't.

The Reality: The Preprocessor is a Copy-Paste Machine

Here is the truth: the C++ preprocessor is effectively a glorified text editor. When it sees #include "game_settings.h", it doesn't "link" anything. It literally deletes that line and pastes the entire contents of game_settings.h right there in its place.

So, in the example above, your physics.cpp ends up with int gravity = -9.81; and your main.cpp also ends up with int gravity = -9.81;. Since both files are compiled into the same final executable, the linker finds two different variables with the same name and panics. I can't tell you how many hours I've wasted in my early career fighting this because I didn't realize I was just copy-pasting code.

Declarations vs. Definitions

To fix this, you have to understand the distinction between a declaration and a definition. This is the core of how C++ manages memory and visibility.

  • Definition: This tells the compiler to actually allocate memory. int gravity = -9.81; is a definition.
  • Declaration: This is just a "heads-up." It tells the compiler, "Somewhere in this project, a variable named 'gravity' of type 'int' exists. Trust me on it; you'll find the actual memory address during the linking phase."

In your header, you should almost always use declarations. In your source files, you provide the single, definitive definition.

Sharing State with the extern Keyword

To properly share that gravity variable across your engine, you use the extern keyword. This turns a definition into a declaration. Here is the professional way to handle this:

// game_settings.h
// This is a DECLARATION. No memory is allocated here.
extern int gravity; 

// game_settings.cpp
// This is the DEFINITION. Memory is allocated once here.
int gravity = -9.81; 

Now, when you include game_settings.h in ten different files, you're just telling the compiler ten times that gravity exists. The linker then connects all those references to the single definition living in game_settings.cpp. It's a bit more manual than what you're used to in managed languages, but it gives you absolute control over where your data actually lives in memory.




📋 Practical Task

Fixing the Double-Definition Conflict in a Physics Engine

You have been handed a project with a critical linker error. The previous developer tried to define a global playerScore variable inside a header file, and now the project won't compile because it's included in both ui_manager.cpp and game_logic.cpp.

Your Task:

  • Modify globals.h so that playerScore is declared but not defined.
  • Create or modify globals.cpp to provide the single, actual definition and initial value for playerScore.
  • Ensure that ui_manager.cpp and game_logic.cpp can both access and modify the value without triggering a "multiple definition" error.

Starter Code:

// globals.h
int playerScore = 0; // This is causing the error!

// ui_manager.cpp
#include "globals.h"
void updateUI() { /* uses playerScore */ }

// game_logic.cpp
#include "globals.h"
void addPoint() { playerScore++; }
Rating
0 0

There are no comments for now.

to be the first to leave a comment.