-2

I have been stuck with a problem in C++ for several hours now, and I can't figure out what's going on, even with the help of the debugger.

I am trying to create a Date class which (no kidding) represents a date, with day, month and year. I also want to overload the main operator (++, --, +=, -=, +).

For a reason I cannot see, everything seems working fine, except the operator '+'.

Here is my header file:

#include <ostream>

class Date {
public:
    Date(int year, int month, int day);
    ~Date();
    Date(const Date& date);
    Date &operator+(int days);

private:
    int m_year;
    int m_month;
    int m_day;
    friend std::ostream &operator<<(std::ostream &os, const Date &date);
};

Here is my C++ file:

#include "Date.h"

using namespace std;

Date::Date(int year, int month, int day)
        : m_year(year),
          m_month(month),
          m_day(day)
{}

Date::~Date() {}

Date::Date(const Date &date)
    : m_year(date.m_year),
      m_month(date.m_month),
      m_day(date.m_day)
{}

ostream &operator<<(ostream &os, const Date &date) {
    os << date.m_day << ", " << date.m_month << " " << date.m_year;
    return os;                                                  <---- debug point A
}

Date &Date::operator+(int days) {
    Date newDate(*this);
    newDate.m_day = newDate.m_day + days;
    return newDate;                                             <---- debug point B
}

And my main file:

#include "Date.h"
#include <ostream>

using namespace std;

int main(int argc, char *argv[])
{
    Date date(2013, 12, 12);
    cout << date << endl;
    cout << date + 2 << endl;
    return 0;
}

And the output is:

12, 12 2013
1359440472, 12 2013

Process finished with exit code 0

I don't understand where does this 1359440472 comes from!!

I have tried to put debug point (as shown above), and the output is the following:

Debug point A:
    date = {const Date &} 
         m_year = {int} 2013
         m_month = {int} 12
         m_day = {int} 12

Debug point B:
    this = {Date * | 0x7fff5c5ddac0} 0x00007fff5c5ddac0
         m_year = {int} 2013
         m_month = {int} 12
         m_day = {int} 12
    days = {int} 2
    newDate = {Date} 
         m_year = {int} 2013
         m_month = {int} 12
         m_day = {int} 14

Debug point A:
    date = {const Date &} 
         m_year = {int} 2013
         m_month = {int} 12
         m_day = {int} 1549654616

I cannot explain that!! There is no step between the two last debug checkpoints, and "14" has become "1549654616"...

It could be a problem with the type int (as it seems to be not far from 2^24) or a problem with the operator +, but I don't see how to fix it.

Thanks you for your help, Ed

Edouard Berthe
  • 1,393
  • 2
  • 18
  • 38
  • You're returning a local object by reference, don't do that. – tkausl Nov 20 '16 at 16:29
  • 1
    @tkausl: You're answering in the comments section; don't do that. – Lightness Races in Orbit Nov 20 '16 at 16:31
  • Thanks for your answer, it was the first time I was facing this problem of handling return by value/reference (I found a satisfactory explanation in http://www.learncpp.com/cpp-tutorial/74a-returning-values-by-value-reference-and-address/). – Edouard Berthe Nov 20 '16 at 16:36
  • I simply would like to stress the fact that: (i) I put a descriptive title and an as explanatory as possible description of my problem, (ii) I tried to solve it by myself, using debugger tools and spending time and (iii) (most important) I DO have checked on SO if other people had the same problem. However, as you can see, nothing was telling me that it was a problem of returning by value/reference, so I didn't know what to look for (if I knew, I wouldn't have asked). I totally understand that my question has to be flagged as 'Duplicate', however I do not see the point of downgrading it. – Edouard Berthe Nov 20 '16 at 16:59
  • @Edouardb: Don't take it personally. Your question is well-presented. It's just that it's so basic and common to be of little value to other readers, and that's what this place is really all about. Next time you'll use the proper learning materials before asking :) – Lightness Races in Orbit Nov 20 '16 at 17:03

2 Answers2

1

You're returning a dangling reference.

Anything can happen.

Make your operator+ return by value.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Thanks for your quick answer. It worked perfectly. I think I was concretely lacking knowledge about basic C++. I found this article explaining what I needed to know: http://www.learncpp.com/cpp-tutorial/74a-returning-values-by-value-reference-and-address/. – Edouard Berthe Nov 20 '16 at 16:34
  • @Edouardb: Instead of random "tutorials" on the internet, you should learn C++ from [a good book](http://stackoverflow.com/q/388242/560648). – Lightness Races in Orbit Nov 20 '16 at 16:36
  • You are right. I didn't follow the tutorial I linked though. I followed a [pretty good tutorial](https://openclassrooms.com/courses/programmez-avec-le-langage-c) (in french), but of course nothing is better than a good book (you can argue that a good tutorial would have talked about returning by value/reference...). – Edouard Berthe Nov 20 '16 at 16:50
  • @Edouardb: How do you know whether the tutorial is good? :) – Lightness Races in Orbit Nov 20 '16 at 16:57
  • Indeed, I cannot know. This website is really well-known in the french developers community for the quality of its tutorials, and it has [raised funds](http://www.journaldunet.com/), and has been [talked about](http://www.journaldunet.com/web-tech/start-up/pierre-dubuc-interview-pierre-dubuc-openclassrooms.shtml) (once again, sorry for the french references...). I learned almost everything I know on it (Python, Java, C, PHP). But once again you can ask: "How do you know you know something?" :) I am absolutely convinced that books are better, but also can be expensive. I'll have a look! thx – Edouard Berthe Nov 20 '16 at 17:06
0

You are returning a reference to a variable with automatic storage duration.

The behaviour on doing that is undefined.

The fix is to return a value, not a reference. Rely on named return value optimisation to obviate an apparent deep copy.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483