Ask Reuben

int_flag

What is int_flag? 

Why is my program acting as if the user pressed Cancel when they did not?

There have been programs coming through the support desk that show lack of understanding of the int_flag variable.

int_flag is a predefined variable set to TRUE when an interruption event is detected or when a cancel action is fired in a singular dialog.  The only thing that sets the int_flag back to FALSE is if the developer explicitly codes it.

You should have a programming standard on the use of int_flag within your organisation.

There are two key pieces of documentation on int_flag

I have touched on the int_flag in two earlier Ask-Reuben articles

The key things you should make sure your programming standards cover are …

  • Make sure DEFER INTERRUPT is set at program start.  If you have an initialisation function that every program calls at start, this line will typically be included here.
  • When the interrupt flag is set to TRUE (1), make sure the code sets it back to FALSE (0)
  • Be consistent in your use of DIALOG, ACCEPT DIALOG, CANCEL DIALOG

As a little exercise, note with the following what value is displayed if you press OK or if you press Cancel

INPUT BY NAME rec.*
    AFTER INPUT
        DISPLAY "After Input",int_flag
END INPUT
DISPLAY "End", int_flag

Click OK you see …

After Input 0
End 0

Click Cancel you see …

After Input 1
End 1

Now also note when DIALOG is introduced into the mix, it is CANCEL DIALOG sets the int_flag to 1

DIALOG
    INPUT BY NAME rec.*
        AFTER INPUT
            DISPLAY "After input",int_flag
    END INPUT
    ON ACTION accept
        DISPLAY "Accept",int_flag
        ACCEPT DIALOG
    ON ACTION cancel
        DISPLAY "Cancel",int_flag
        CANCEL DIALOG
END DIALOG
DISPLAY "End", int_flag

Clicking OK you see. …

Accept 0
After Input 0
End 0

Clicking Cancel you see it is the CANCEL DIALOG that sets int_flag to 1, not the ON ACTION cancel …

Cancel 0
After input 1
End 1

In both cases, note the value of int_flag after the dialog has been exited after clicking Cancel.  The value of int_flag is still set to 1.  This is noticeable if you have two consecutive dialogs …

INPUT BY NAME rec.*
    AFTER INPUT
        DISPLAY "After Input 1",int_flag
END INPUT
DISPLAY "Inbetween", int_flag
INPUT BY NAME rec.*
    AFTER INPUT
        DISPLAY "After Input 2",int_flag
END INPUT
DISPLAY "End", int_flag

… note what happens when you click Cancel then OK

After Input 1 1
Inbetween 1
After Input 2 1
End 1

… int_flag is still set to 1 in the AFTER INPUT of the second dialog. So even though the user clicked OK, the runtime will proceed as if Cancel was clicked. The correct thing to do is to add a LET int_flag = 0 between the two input statements.

INPUT BY NAME rec.*
    AFTER INPUT
        DISPLAY "After Input 1",int_flag
END INPUT
DISPLAY "Inbetween", int_flag
LET int_flag = 0   -- Make sure int_flag is reset
INPUT BY NAME rec.*
    AFTER INPUT
        DISPLAY "After Input 2",int_flag
END INPUT
DISPLAY "End", int_flag

From a coding standards perspective, you need to ensure that you have a LET int_flag = 0 to set the value of the int_flag back to 0. It is not set to 0 by the dialog starting, nor is it set to 0 when the user clicks OK.  The coding standard I was brought up with was to set int_flag back to 0 after every dialog statement. I have seen other standards to set it to 0 explicitly before each dialog statement but that does not handle the case of the int_flag being set to 1 by a nested dialog. I was also brought up to put the LET int_flag = 0 line in a function and it was this function that was called at the end of each dialog statement.  (Note: I have put dialog in italics as it means each INPUT, INPUT ARRAY, CONSTRUCT, PROMPT, DISPLAY ARRAY, DIALOG (with CANCEL DIALOG) statement, not each DIALOG statement).

The mistake we typically see is forgetting to set int_flag back to 0, and that is due to the lack of a clear enforced coding standard.

I believe you can avoid the use of int_flag if you wrap each dialog statement in DIALOG and use an explicit ON ACTION accept, ON ACTION cancel without using CANCEL DIALOG).  If you are prepared to make that change through your code base, that might be a technique to explore, and just save int_flag for interrupting database operations and loops.