Declaring resources as needed without duplicating them

68 views Asked by At

Say I'm simulating food for a population:

Eat.cpp:

void eat()
{
    food--:
}

Hunt.cpp:

void hunt()
{
    food++;
}

eat() and hunt() both depend on the integer food. But my population simulator might include both, one, or neither of these files. How do I ensure that food only exists if something is included that will use it, and will only be declared once if multiple files use it? Currently my best idea is a sort of header guard, e.g.:

#ifndef FOOD
#define FOOD
int food = 10;
#endif
3

There are 3 answers

0
Andreas Wenzel On

You could define the variable food in one central file (even if that file doesn't use it) and then declare it extern in every other file that uses it. A good optimizer may be able to optimize the variable away if it is never used or referenced. I have never tested it, though.

However, this will likely not work if initialization is required. If initialization is required, you will likely want to ensure that the variable is only initialized once. This initialization would have to be done in one file only and would likely prevent the variable from being optimized away, because the variable was used (even if it was only used for initialization).

Therefore, using the preprocessor for conditional compilation, as you have described in your question, would probably be the best option.

0
CiaPan On

Just add a food.cpp module with the public variable:

int food = 0;

Also add a header file food.h with its declaration:

extern int food;

and include it:

#include "food.h"

in all modules (food.cpp, hunt.cpp and eat.cpp).

This way all modules will be using the same variable, defined once in the dedicated module.

BTW, this is rather C-like way of designing things, not C++.

1
hegel5000 On

You can keep full control over how many times food is allocated (e.g. just once), along with its starting value, by making it a variable which should be local to whatever function manages and initiates the population simulation. eat and hunt should then be parametrized with this (one and only) instance of food:

Eat.cpp:

void eat(int & food) { food--; }

Hunt.cpp:

void hunt(int & food) { food++; }

Here is an example simulation in which only one instances of food is guaranteed to exist, and where Hunt.cpp is never touched.

no_hunt_simulation.cpp:

#include "Eat.h"

void no_hunt_simulation(int & food) {
  while (food) { eat(food); }
}

main.cpp

#include "no_hunt_simulation.h"

int main() {
  int food = 5;
  no_hunt_simulation(food);
  std::cout << "Remaining food: " << food << std::endl; //it's 0
}

With -Wall, GCC will remind you (or a library user) if food is not used, in which case you can just not declare it, preventing it from being allocated.