2

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".

A. Park
  • 94
  • 1
  • 10

1 Answers1

3

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.

YSC
  • 38,212
  • 9
  • 96
  • 149
  • `struct tm` isn't a POD, but a structure. Nevertheless, without a defined constructor your statement that it is uninitialized is true, and the crux of the OPs question. – jwm May 30 '18 at 00:29
  • 1
    @jwm why do you think that structures can't be PODs? A [POD class type](https://en.cppreference.com/w/cpp/concept/PODType) is a class (class/struct/union) type that is trivial, standard layout, and has no non-static, non-POD members. `tm` absolutely meets this definition. The answer links to this same definition of POD, btw. And "without a defined constructor" isn't the issue. A non-POD type that has no user-defined constructors **would** be initialized by an expression `T t;`, using the [default constructor](http://en.cppreference.com/w/cpp/language/default_constructor). – monkey0506 May 30 '18 at 01:24
  • Amending my comment above, note that `T t;` would invoke the compiler-generated `T()` constructor, but it would not initialize members of built-in types (`int` data members, for example). – monkey0506 May 30 '18 at 01:34