Reputation: 1976
I am making a namespace to help me debug a program but I'm having a problem figuring out how structure everything and get it to build without issue.
Here's my current header:
#ifndef HELPER_H
#define HELPER_H
#include <string>
#include <fstream>
#include <sstream>
namespace Helper
{
enum LOG { ONSCREEN, OFFSCREEN };
extern std::ofstream logfile;
//std::ofstream logfile("log.txt", std::ios_base::out | std::ios_base::app );
void EnableLogging();
void Log(std::string s, LOG type);
template <class T>
std::string ToString(const T& t)
{
std::ostringstream sstr;
sstr << t;
return sstr.str();
}
}
#endif // HELPER_H
Here's the Helper cpp file:
#include "Helper.h"
#include <cstdio>
void Helper::EnableLogging()
{
#ifdef WIN32
// To use console on pc
std::ofstream ctt("CON");
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
#endif
#ifdef GP2X
//To log to text file on the caanoo
logfile.open("log.txt", std::ios_base::out | std::ios_base::app );
#endif
}
void Helper::Log(std::string s, LOG type)
{
if(type == OFFSCREEN)
{
#ifdef GP2X
//log << "L" << __LINE__ << "|T" << SDL_GetTicks() << "| " << s << std::endl;
logfile << s << std::endl;
#endif
#ifdef WIN32
printf("%s",s.c_str());
#endif
}
}
At the moment I am getting an undefined reference to Helper::logfile error, which I completely understand is because I've used the extern keyword.
Without the extern keyword I get a different error: multiple definition of Helper::logfile . The error is reported as 'first defined..' in another source file that I am trying to include "Helper.h"
in. The line number that error is reported on is a constructor within said source file but I suspect that has little to do with anything.
I'm sure I am structuring the helper code wrong for compile but I can't figure out how I should be doing it?
Upvotes: 0
Views: 601
Reputation: 254431
You need to declare the variable in the header, as you do, to make the name available wherever its needed.
// Helper.h
extern std::ofstream logfile;
You need to define it in the source file; the One Definition Rule requires that you have exactly one definition.
// Helper.cpp
std::ofstream Helper::logfile("log.txt", std::ios_base::out | std::ios_base::app );
With no definition, the variable doesn't exist, hence the "undefined reference" error.
With a definition in the header, it's defined in every translation unit that includes the header, hence the "multiple definition" error.
With a definition in one source file, it's defined once, and the linker is happy.
Upvotes: 2