最佳化程式中的異常狀況

在極少數情況下,在以最佳化等級 30 (*FULL) 或 40 編譯的程式中可能會出現 MCH3601 異常訊息。 本主題說明發生此訊息的一個範例。 以最佳化等級 10 (*NONE) 或 20 (*BASIC) 編譯時,相同的程式不會收到 MCH3601 異常訊息。 此範例中的訊息是否發生取決於 ILE HLL 編譯器如何配置陣列的儲存體。 您的語言可能永遠不會出現此範例。

當您要求最佳化層次 30 (*FULL) 或 40 時, ILE 會嘗試透過計算迴圈外部的陣列索引參照來增進效能。 當您參照迴圈中的陣列時,通常會依序存取每一個元素。 儲存前一個迴圈反覆運算中的最後一個陣列元素位址,即可增進效能。 為了提高效能, ILE 會計算迴圈外部的第一個陣列元素位址,並儲存迴圈內部使用的值。

以下列範例為例:
   DCL ARR[1000] INTEGER;
   DCL I INTEGER;
 
   I = init_expression;   /* Assume that init_expression evaluates
                             to -1 which is then assigned to I */
 
   /* More statements */
 
   WHILE ( I < limit_expression )
 
     I = I + 1;
 
     /* Some statements in the while loop */
 
     ARR[I] = some_expression;
 
     /* Other statements in the while loop */
 
   END;

如果 ARR [init_expression] 的參照產生不正確的陣列索引,此範例可能會導致 MCH3601 異常狀況。 這是因為 ILE 在輸入 WHILE 迴圈之前嘗試計算第一個陣列元素位址。

如果您在最佳化等級 30 (*FULL) 或 40 收到 MCH3601 異常狀況,請尋找下列狀況:
  1. 在使用變數作為陣列元素索引之前,您有一個迴圈會增加變數的增量。
  2. 迴圈入口上的索引變數起始值為負數。
  3. 使用變數起始值的陣列參照無效。
當這些狀況存在時,可能可以執行下列動作,以便仍可使用最佳化等級 30 (*FULL) 或 40:
  1. 將程式中增加變數的部分移至迴圈底端。
  2. 視需要變更變數的參照。
前一個範例將變更如下:
   I = init_expression + 1;
 
   WHILE ( I < limit_expression + 1 )
 
     ARR[I] = some_expression;
 
     I = I + 1;
 
   END;

如果無法進行此變更,請將最佳化等級從 30 (*FULL) 或 40 降低至 20 (*BASIC) 或 10 (*NONE)。