I'm working on a project where I need the following structure:

The 2 CPP files contain classes, those classes need naked functions that are in H File 1. The classes and the nakeds need variables in H File 2.
I can split the CPP files so that they use 2 separate file that contain the nakes and the variables they need. But I prefer to use this structure.
It looks like that the compiler skips the #ifndef command, I made a test for the problem:
Main:
#include <iostream>
//1>CPPFile2.obj : error LNK2005: "bool Test1" (?Test1@@3_NA) already defined in CPPFile1.obj
//1>CPPFile2.obj : error LNK2005: "bool Test2" (?Test2@@3_NA) already defined in CPPFile1.obj
int main()
{
}
CPPFile 1:
#include <iostream>
using namespace std;
#include "HFile1.h"
CPPFile 2:
#include <iostream>
using namespace std;
#include "HFile2.h"
HFile 1:
#include "HFile2.h"
#pragma once
#ifndef Name1
#define Name1
//Use test1, this workes fine
//Use test2, this workes fine
#endif
HFile 2:
#pragma once
#ifndef Name2
#define Name2
bool Test1 = false;
bool Test2 = false;
#endif
How is it possible that the #ifndef #define #endif structure doesn’t work properly?
Your problem is that the second header is defining the variables, not just declaring them. There must be a single definition in the program and thus compilation fails. This is unrelated to include guards, as include guards only protect within a single translation unit. In your case, each one of the .cpp files includes the header and thus define the same variables separately.
The solution would be to only declare the variables in the header and define them in a single translation unit:
#ifndef Name2
#define Name2
extern bool Test1;
extern bool Test2;
#endif
// single .cpp
bool Test1 = false;
bool Test2 = false;
Although there is some code smell around the whole thing. You might want to redesign your solution. The use of global variables is in most cases not a good solution.
You're getting a linking error; this has nothing to do with include guards. You have defined Test1 and Test2 in both object files. Instead, you'll need to ensure that only one object file defines it and the other externs it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With