Search code examples
c++structtmctime

struct tm time; vs tm time = {}. Same output but not the same?


I was doing some programming questions on this website called Kattis. Here is a link to the question I was doing: https://open.kattis.com/problems/datum

While I was trying to solve this, I found out something very, very, very weird.

Before I begin, here are two codes:

First one:

#include <iostream>
#include <ctime>
#include <string>

using namespace std;

int main()
{
    //a = day, b = month
    string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

    struct tm time;

    cin >> time.tm_mday >> time.tm_mon;

    time.tm_year = 2009-1900;
    time.tm_mon--;

    mktime(&time);

    cout << days[time.tm_wday] << endl;

    return 0;
}

Second one:

#include <iostream>
#include <ctime>
#include <string>

using namespace std;

int main() {
    //a = day, b = month
    string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

    tm time = {};

    cin >> time.tm_mday >> time.tm_mon;

    time.tm_year = 2009-1900;
    time.tm_mon--;

    mktime(&time);

    cout << days[time.tm_wday] << endl;

    return 0;
}

They are THE EXACT SAME code except the only difference in these two codes is:

struct tm time; // first code

vs

tm time = {}; // second code

NOW, This is what I found very confusing. The first code and the second code give an exact same answer on my console. I checked the type of the result (days[time.tm_wday]) by doing typeid(days[time.tm_wday]).name() as well and both of the answer seem to be exact same.

However, when submitted into Kattis website, it only accepts the second one and doesn't accept the first one.

Now, can anyone tell me what I'm missing here? Why is it only accepting one vs another? Thank you very much!

EDIT: Some information on Kattis: There would be a question where you would have to solve it by programming. It then checks your answer with theirs. If your program outputs the same answers, it "accepts" your solution. If its different, then it doesn't.

For example, lets say the quetion is to calculate the area of a square. It gives couple examples with values.

ex) Case 1: (input: 5 Output: 25).

If your console outputs 25 when inputted 5, then it "accepts" your solution. If it outputs some random number like, 10, then it doesn't accept.

The thing with my program is that it outputs exact same values:

First code outputs: Thursday. Second code outputs: Thursday etc. However only one is considered "correct".


Solution

  • There are two differences at play:

    struct tm time; // (1)
    

    versus

    tm time = {}; // (2)
    

    1 struct

    In C, the name of a compound type includes the struct keyword, "struct tm" here. In C++, the name of the type is enough by itself, "tm" here; but it can be prefixed by struct for compatibility's sake. More on that: Difference between 'struct' and 'typedef struct' in C++?

    So, regarding the struct keyword, there is in fact only a cosmetic difference.

    2. Initilization

    (1) defines the variable time of type tm. Since tm is a POD, it is not initialized. Using an uninitialized value results in undefined behavior generally.
    (2) defines and list-initializes the variable time of type tm. This in turn zero-initializes tm and the behavior of the program is well-defined.

    More on that: What do the following phrases mean in C++: zero-, default- and value-initialization?

    Why does it matter?

    Not fully initializing time and then calling mktime(&time); results in Undefined Behavior. Everything can happen. It may be different each time you run your program, it can depend on the exact compiler used, the libs it is linked against, the OS, the hardware, anything, everything. It can also work as expected. More on that: Undefined, unspecified and implementation-defined behavior.

    I suspect the program works by chance on your environment, but fails on the target.