You are not logged in.
Hi all,
I'm writing quite a big C++ project (for me, surely :-), and I ran into big troubles with inclusion and declaration. To make access easier and faster to some often used data, I made it global and placed in a namespace. But then came troubles - I get errors about multiple declaration or about undefined variables. I simplified situation to the following sample:
-------main.cpp:
#include <iostream>
#include "header.hpp"
int main()
{
using std::cout;
using std::endl;
cout << "Test" << endl;
std::string m("a message");
SetMessage(m);
PrintMessage();
return 0;
}
-------header.hpp:
#ifndef HEADER_HPP
#define HEADER_HPP
#include <iostream>
void PrintMessage();
void SetMessage(std::string msg);
namespace module
{
std::string message;
}
#endif // HEADER_HPP
-------header.cpp:
#include "header.hpp"
void SetMessage(std::string msg)
{
using namespace module;
message = msg;
}
void PrintMessage()
{
std::cout << "Message is: " << module::message << std::endl;
}
I googled but the only solution I found was using extern keyword. But namespace module is internal from header.* standpoint and isn't used/mustn't be defined in main.cpp. Now I simply haven't got any idea how to solve it.
How can it be corrected?
Last edited by Kosmonavt (2010-11-07 09:15:51)
Offline
read about inclusion guards.
Offline
It looks to me like your inclusion guards are okay.
Aside from exposing the module namespace in header.hpp, it looks okay to me.
Does this example fail to compile? Where and how?
As to the module namespace, i would define it in header.cpp as main has no need to know.
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
Since you only want a single instance of message anyway I think the easiest would be to just make it a "static std::string", that makes it compile and run fine for me.
I haven't lost my mind; I have a tape back-up somewhere.
Twitter
Offline
To Allan: there are header guards.
To ewaller: basically it's true, but this namespace is not an implementation, but some sort of declaration. So it's more logical to place it in header. This sample threw "multiple declaration" linker error while building it with g++ -Wall $(SOURCES).
Looks like it's the following sort of problem: preprocessing being run on main.cpp includes into it's code all the header.hpp, similarly header.hpp is included in header.cpp. Still, strange that it wasn't parsed as a whole.
And yes, static declaration of all variables/constants in namespaces helped (thanks Zeist!). It was so easy that I hadn't thought about it. Marking as solved.
Last edited by Kosmonavt (2010-11-07 09:17:57)
Offline
"static" is probably not what you want, for two reasons:
1) C++ supports anonymous namespaces, which are more "the C++ way." To use them, you'd write:
namespace module {
namespace {
std::string message;
}
}
2) If you make a static/anonymous std::string in header.hpp, there's a useless std::string added to every translation unit that includes it. Instead, only declare and define module::message in header.cpp itself. That would look like this:
header.hpp:
#ifndef HEADER_HPP
#define HEADER_HPP
#include <iostream>
void PrintMessage();
void SetMessage(std::string msg);
#endif // HEADER_HPP
header.cpp:
#include "header.hpp"
namespace module { // nb: you don't really need this namespace now
namespace {
std::string message;
}
// Alternatively:
// static std::string message;
}
void SetMessage(std::string msg)
{
using namespace module;
message = msg;
}
void PrintMessage()
{
std::cout << "Message is: " << module::message << std::endl;
}
Offline