Hello,
Here is my example code:

// Main.h

#ifndef MAIN_H
#define MAIN_H


#include <iostream>
using namespace std;
#include <string.h>

string HelloWorld = "Hello World!\n";
void HelloEarth();

#endif
// Main.cpp

#include "Main.h"

int main()
{
    cout << HelloWorld;
    HelloEarth();
}
// Secondary.cpp
#include "Main.h"

void HelloEarth()
{
    cout << HelloWorld;
}

Problem is, it appears the #ifndef and #define tags aren't stopping Secondary.cpp from redeclaring HelloWorld.
When I attempt to compile and run, the IDE (in my case Code::Blocks) opens up a file called "locale_facets.tcc" and shows an error on line 2497.
This is the message I get for the error:

obj\Debug\Main.o||In function `ZSt17__verify_groupingPKcjRKSs':|
C:\Program Files (x86)\CodeBlocks\bin\..\lib\gcc\mingw32\3.4.4\..\..\..\..\include\c++\3.4.4\bits\locale_facets.tcc|2497|multiple definition of `HelloWorld'|
obj\Debug\Secondary.o:C:\Program Files (x86)\CodeBlocks\bin\..\lib\gcc\mingw32\3.4.4\..\..\..\..\include\c++\3.4.4\bits\locale_facets.tcc|2497|first defined here|
||=== Build finished: 2 errors, 0 warnings ===|

Does anyone know what I did wrong?

Recommended Answers

All 8 Replies

Put the #ifndef around it.

Put #ifndef around what?

You can't declare an instance of a variable more than once. That's what's happening. Try this:

// Secondary.h
#ifndef SECONDARY_H
#define SECONDARY_H

#include <iostream>
using namespace std;
#include <string.h>
extern string HelloWorld;

void HelloEarth();

#endif

Change Main.cpp and Secondary.cpp to include "Secondary.h", remove the function declaration of "HelloEarth" from Main.h, and remove the include for Main.h in Secondary.cpp. This allows you to declare the variable once in Main.h, and reference it from other places.

commented: Got straight to the point and showed me what was wrong with my code +2

Put #ifndef around what?

HelloEarth()

Ah thank you so much, both of you! =)

Problem is, it appears the #ifndef and #define tags aren't stopping Secondary.cpp from redeclaring HelloWorld.

Does anyone know what I did wrong?

Your include guard is correct, but it is designed for a different kind of problem, like this:

// Main.cpp

#include "Main.h"
#include "Main.h"

int main()
{
    cout << HelloWorld;
    //HelloEarth();
}

The above code will still compile fine because you've protected against Main.h being included more than once in the same compilation unit.

Each CPP file is a separate compilation unit, so both Main.cpp and Secondary.cpp are going to be able to include Main.h , even with the include guard.

The error message actually says multiple definition, not declaration. The problem isn't that you've declared HelloWorld in the header, it's that you've given it a value there. Because each CPP file includes the header separately, you've given it a value twice--this is what the compiler's complaining about.

You can still declare HelloWorld in Main.h , and you must if you want to refer to it from multiple CPP files, but you can only give it a value in one place. It doesn't really matter where, as long as the file that contains the definition is compiled into the final executable.

Here's one way you could do it:

// Main.h

#ifndef MAIN_H
#define MAIN_H


#include <iostream>
using namespace std;
#include <string.h>

extern string HelloWorld;
void HelloEarth();

#endif
// Main.cpp

#include "Main.h"

string HelloWorld = "Hello World!\n";

int main()
{
    cout << HelloWorld;
    HelloEarth();
}
// Secondary.cpp
#include "Main.h"

void HelloEarth()
{
    cout << HelloWorld;
}

Note the use of extern . That's basically telling the compiler, "Hey, there's a string called 'HelloWorld', but it's defined somewhere else." If you don't use this keyword, you'll get the same "multiple definition" error, because even if you don't give it a value explicitly, it still gets one--in this case, the empty string.

With extern , both Main.cpp and Secondary.cpp know that HelloWorld is a string and can use it as such. If you forget to give HelloWorld a value somewhere, you'll get a linker error--the compiler is perfectly happy.

commented: Did more than just gave me the code to fix the error, he explained the causes very clearly and overall did a great job replying. +2

Oh wow, you answered that very well. One other question: say a variable is declared extern in the global namespace. Will it still retain its value throughout all files it's used in? For example,

// Example.h
extern int a;
// Example1.cpp
#include "Example.h"
a = 10;
// Example2.cpp
#include "Example.h
cout << a;

Will it display 10 or will the value of a get lost between files?

say a variable is declared extern in the global namespace. Will it still retain its value throughout all files it's used in?

Will it display 10 or will the value of a get lost between files?

You still need to include the type of a in Example1.cpp , like this:

int a = 10;

If you put a main function around the code in Example2.cpp , it should display "10".

You can declare extern int a; any number of times, but you can only give it a value once, and that will be the value it starts with.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.