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