-3

I've gone over many questions with the same or similar titles, I have changed the code in so many ways I can't even count.... I have an interesting problem.
I have a class for logging that is extremely simple and just writes stuff into a file. The exact same code works in the constructor, but will not work in the member function. I'm stripping out some irrelevant code, the rest is:

private:
    std::string logfile_path_;
    std::string program_name_;
    std::string GetTimestamp() {
        timeval tv;
        gettimeofday(&tv, NULL);
        char cTimestamp[24];
        strftime(cTimestamp, sizeof(cTimestamp), "%F %T", std::localtime(&tv.tv_sec));
        sprintf(&cTimestamp[19], ".%03d", (tv.tv_usec / 1000));         // write the miliseconds (microseconds/1000) into cTimestamp starting at the 20th character. %03d == pad with 0, for a minimum length of 3, an integer.
        return cTimestamp;      // function returns std::string so this will be implicitly cast into a string and returned.
    }

public:
    int log_level_;

    SrxDsLog(std::string Logfile_path, std::string program_name, int log_level) {
        log_level_ = log_level;
        program_name_ = program_name;
        logfile_path_ = Logfile_path;
        std::ofstream logfile(logfile_path_.c_str(), std::ios::out | std::ios::app);
        std::cout << "Logger started, Log file: " << logfile_path_ << std::endl;
        logfile << "Logger started, Log file: " << logfile_path_ << std::endl;
        return;
    }

    void WriteLog(std::string Log_message, int Severity = LOG_CRITICAL, std::string Function_name = "") {
        if (Severity >= log_level_) {
            std::cout << GetTimestamp() << "|" << program_name_ << "|" << Function_name << "|" << GetSeverity(Severity) << "|" << Log_message << std::endl;
            std::ofstream logfile(logfile_path_.c_str(), std::ios::out | std::ios::app);
            logfile << GetTimestamp() << "|" << program_name_ << "|" << Function_name << "|" << GetSeverity(Severity) << "|" << Log_message << std::endl;
        }
    }

The question is why is it working in the constructor, but the exact same code is not working in the member function. The std::cout is writing the exact same log message I want, but it's not appearing in the file. The file contains a single line every time the program is run.

xyious
  • 1,065
  • 4
  • 13
  • 29
  • Er, that is _not_ exact same code in ctor and member function. In fact, it shouldn't compile, as `logfile` only exists in ctor. – Dúthomhas Sep 22 '17 at 17:48
  • I'm declaring logfile in both functions. – xyious Sep 22 '17 at 17:49
  • @NeilButterworth what's the alternative ? Not logging isn't it. I guess I could redirect cout and cerr ?? The amount of effort saved there is negligible. – xyious Sep 22 '17 at 17:52
  • You don't set the `log_level_` member anywhere, so it is still uninitialized. – 0x5453 Sep 22 '17 at 17:52
  • @0x5453 yes, at this point log_level_ is uninitialized (0), I do set it later, but that's not important to the question. – xyious Sep 22 '17 at 17:54
  • "what's the alternative " - use an existing one. –  Sep 22 '17 at 17:57
  • @xyious It *is* important to the question; the code posted here exhibits undefined behavior. We can't guess your problem beyond that if we don't have an example that shows all of the relevant information. (Also worth noting, "Uninitialized" != "initialized to 0".) – 0x5453 Sep 22 '17 at 17:59
  • Everything I've read says class members set to 0 on initialization, can someone provide a link that refutes it ? – xyious Sep 22 '17 at 18:10
  • 2
    After the `std::ofstream logfile...` line, you should [check to see if the file actually is opened](https://stackoverflow.com/q/6255339/669576). – 001 Sep 22 '17 at 18:11
  • @xyious https://blog.tartanllama.xyz/initialization-is-bonkers/ – 0x5453 Sep 22 '17 at 18:13
  • @JohnnyMopp logfile.is_open() returns true in constructor, false in member function. – xyious Sep 22 '17 at 18:21
  • Ok. Probably somewhere the file is being opened but not closed. Do you access that file anywhere else in the program? Or is there another program running on your system that might be using it? – 001 Sep 22 '17 at 18:26
  • The file is not accessed in other programs and the only functions writing to it are posted above. I used to have a member variable ofstream and I would logfile.open() in the constructor and logfile.close() in the destructor, but that also had the same result. At the same time, the same code was working in a different program with a different logfile. – xyious Sep 22 '17 at 18:29

2 Answers2

2

In an amazingly unsatisfying turn of events I voted to close my question.
The problem was apparently caused by undefined behavior in unrelated code. And that because I did something that's defined in C++11 but is not in C++03. Apparently you can't call constructors from constructors in C++03....
Because of that, and because the question didn't include the code that was actually at fault, the question seems incredibly bad.

Please close.

xyious
  • 1,065
  • 4
  • 13
  • 29
1
int log_level_;

The constructor fails to initialize this class member.

Subsequently, the comparison with this class member results in undefined behavior.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I thought class members are zerod ? Either way I'm getting an output and I had previously written log_level_ in a message to cout which returned 0 until I explicitly set it later. – xyious Sep 22 '17 at 17:55
  • Regardless, it's evaluated once, then I'm writing to cout (successfully) and writing to the log file (which fails). This logically can not be the answer. – xyious Sep 22 '17 at 18:00
  • @xyious Initialization rules in C++ are a little messy, but in this case a primitive `int` will remain uninitialized. It may be 0, or it may not be, depending on the state of memory. However, reading from an uninitialized variable is undefined behavior, so any logic about the preceding `if` statement gets thrown out the window. – 0x5453 Sep 22 '17 at 18:02
  • OK, changed the code (and the question). No change in behavior. – xyious Sep 22 '17 at 18:04