Caveat: Using the += and -= operators for dates.


As you may know, it is possible in X++ to add integers to dates. The semantics are that the integer value is considered a number of days to add or subtract to the date.

{
   Date d;
   // …
   d = d + 7; // Seven days later
   // …
   d = d – 7; // Seven days prior.
}

The example above works well. However, the programmer may see the code above and decide that it can be expressed more succinctly by using the composite assignment operators +=  and -=. In the case above there is no gain by using these, but in cases where the lefthand side is very complex (involving lots of method calls with side effects) a case can be made for the argument that it should be replaced with += and -=.


The obvious thing to do then is:

{
   Date d;
   // …
   d += 7; // Seven days later
   // …
   d -= 7; // Seven days prior.
}

This too will work as expected. The problem occurs if you try to use the += operator to subtract days or the -= operator to add days; that is, supplying a negative number of days to add or subtract.

{
   Date d;
   // …
   d += 7; // Seven days later
   // …
   d += –7; // ERROR Seven days prior.
}

The problem is based in the fact that the compiler will generate code to do a type conversion from the integer argument to a date, which will succeed for positive values, but not for negative ones. It is not easy to fix, but in due course we will, either by disallowing the composite assignment operators on dates or by throwing an exception when the argument is negative.


To make matters even worse, the kernel will simply show a dialog box but continue execution with wrong data afterwards.


The learning from all this is that if you use these operators for dates, you must make sure the expressions on the right hand side always evaluate to non-negative values. If you cannot guarantee this, use the d = d + expr syntax instead.


 


 


 

Comments (3)

  1. JanKjeldsen says:

    I have personally experienced this problem.

    "It is not easy to fix", you can’t be serious.

    How difficult is it to add or subtract a negative number!?!

    Dates are internally represented as integers, so whats the deal?

    "either by disallowing the composite assignment operators on dates or by throwing an exception when the argument is negative"

    The first option is vandalizing the language, the second outright stupid, as it gives run time errors.

    The right option is to do it right, allow negative increments, and only throw if the resulting date becomes negative (pre 1900).

  2. mfp says:

    Will the same happen if the negative number is contained within a variable instead of being a literal?

    Best fix would be to make the kernel do the math right; alternatively fail hard instead of continue with corrupt data.

  3. c_makarov says:

    I am sorry, but why it is considered to be "not easy to fix"?

    It is a wrong design of compiler IMHO, but if nobody can fix the compiler, there are another ways to solve a problem.

    Where is a "If you cannot guarantee this, use the d = d + expr syntax instead." in the article, and if I were compiler writer and unable to redesign compiler, I better make a workaround to convert text "d += expr" to "d = d + expr" at the point compiler know "d" is a date but before compiling to code.

    I think, it is not an impossible task.

    Sorry.