I need to use a static fstream in multiple source files. However I can only use it from a single file and not from the others. Furthermore, its use in the other files does not give any error, it just does nothing.
This is the code:
/// log.h
#ifndef LOG_H
#define LOG_H
#include <fstream>
static std::ofstream ofs;
#define LOG(level) ofs << level << ": "
#endif
/// test.cpp
#include "log.h"
#include "other.h"
int main()
{
ofs.open("file.log");
LOG(5) << "Test log 1" << std::endl; // OK
OtherFunc();
}
/// other.h
#ifndef OTHER_H
#define OTHER_H
extern int OtherFunc();
#endif
/// other.cpp
#include "other.h"
#include "log.h"
int OtherFunc()
{
LOG(5) << "Test log 2" << std::endl; // Nothing
}
This is the generated file:
5: Test log 1
Thank you!
Platform:
Linux
g++ 4.5.1
statichere means you’re explicitly asking the compiler to give the file-scope variablestd::ofstream ofsstatic linkage, which means it is visibly only in the current file.The twist is that you’re doing this in a header, which means every
.cppfile including the header gets its own distinct instance ofstd::ofstream ofs. Only because you’ve given it static linkage can they all have distinct file-scope variables with the same name – otherwise there would be a name clash.So, in
main.cpp, you open your localofsand write to it.In
other.cpp, you have your own local copy ofofs, but never open it … so the output doesn’t go anywhere, and certainly not tofile.log.The other answers are correct, that changing the header declaration to
extern std::ofstream ofs;will allow all the.cppfiles to share a single object calledofs, and then you just need to put the instance in exactly one place (main.cppwould be fine).It might be simpler, and cleaner, to make the
LOG(level)an out-of-line function call though; then the output stream could live in alog.cppwith the function definition, and nobody else needs to see it.