when

wrong usage of ASSIGN..WHEN.. statement

Rule "when" gives this warning when it finds an ASSIGN statement with a WHEN clause, if the WHEN clause reads variables that are assigned to in that same ASSIGN statement.

DEFINE VARIABLE a AS INTEGER INITIAL 1.
DEFINE VARIABLE b AS INTEGER INITIAL 2.
DEFINE VARIABLE c AS INTEGER INITIAL 3.
DEFINE VARIABLE d AS INTEGER INITIAL 4.
ASSIGN 
   a = b
   c = 100 WHEN (a = b).
/* c is now still 3 */
ASSIGN 
   a = b
   c = 200 WHEN (d = 4).

You might expect that (a = b) is True after executing the first line, so c will be assigned the value 100.

It doesn't work that way. All WHEN clauses are evaluated first (a = b is still False) before any assigments take place.

Prolint will not complain about the second ASSIGN statement because the WHEN clause does not access any variables that are on the left-hand side of any of the = signs.

the risc:

It is not commonly known that the boolean values of WHEN clauses are evaluated before the assignments take place. Either the program will not do what the programmer intended, or the program is confusing to most other programmers.

how to solve this:

Try to avoid using WHEN in an ASSIGN statement; rewrite to IF.

How to suppress these warnings:

You can put the directive {&_proparse_ prolint-nowarn(when)} directly before
the ASSIGN statement. See also: suppress warnings.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Could be improved

This rule should exclude lines where the variable/field being assigned is used in a when clause on the same line, for example:

assign
customer.credlimit = DfltCrefLimit when customer.credlimit = ?.

There's nothing wrong with this structure.

-Tim Townsend


jurjen's picture

Re: Could be improved (when)

I know, this was mentioned before in issue 635 (see issue 635) but I don't know of an algorithm to fix it without false negatives. If you have suggestions, please tell me.


Re: Could be improved (when)

Is it really that hard? I would think it would just be:

for each variable-or-field-referenced-in-when-clause:
  if can-find(first assign-target where assign-target.assign-stmt = this-assign-stmt and
              assign-target.line-num lt this-line-num) then
    message "Houston we have a problem".

IOW, we are looking for fields that are referenced in a when clause and that are assigned a value on a previous line in the same assign statement, since that is the case where Progress' behavior is not what you might expect. Or maybe I'm missing something, it's happened before. :)

-Tim Townsend


jurjen's picture

Re: Could be improved (when)

If you are missing it, then I am missing it too. Looks like a solution to me.
Issue 635 is reopened :-)