序列點之間物件被修改一次以上求值順序未指定 ;
序列點之間物件可能被修改和讀取求值順序未指定 ;
'&&'或' ' 的右運算元是一個可能發生副作用的表示式。
工具/原料
Rule13.2 0400 0403 Rule13.5 3415
MISRA C:2012
Rule13.2 0400
0400 [U] '%s' is modified more than once between sequence points - evaluation order unspecified.
序列點中物件被修改一次以上,操作結果是未定義的。
在C中,副作用的順序沒有很好地被定義。 如果在兩個序列點間,物件被修改一次以上,C語言沒有定義這兩次更新的順序。 當在序列點間,一個物件被明確修改一次以上時,生成訊息0400。 修改物件的明確運算包括賦值運算、自增和自減運算等。
在下面的例子中,賦值運算的右運算元表示式會被計算成10。這條語句中"x"會被修改兩次,一次是自增運算,一次是賦值運算。但C語言中沒有明確指定這兩種更新運算中哪個應該先執行。有的編譯器會先用10賦值,然後自增到11,有的編譯器會先把x自增到3,然後再進行賦值運算,把x賦值為10。
程式設計規範修改舉例
Rule13.2 0403
0403 [U] '%s' may be modified and accessed between sequence points - evaluation order unspecified.
序列點間,物件可能被同時修改和讀取。ISO:C 標準認為,在序列點間,和賦新值不一樣,物件的修改和讀取操作結果未定義。
如果使用了物件的值,同時,物件的值在同一條語句中被修改,那麼這種情況下確定物件值的修改操作在其使用前還是使用後很重要,但這沒有定義。
當讀取物件和可能修改物件的順序未定義時生成訊息0403。 物件的地址傳入函式,且函式引數沒有定義為"指向const限定"型別的指標時,屬於可能修改的程式碼。 這種情況下,QAC不能確定呼叫的函式有沒有真的修改物件的值,函式引數被簡單識別為可能修改。
在如下所示的程式碼例子:
語句a)中,對"x"的明確修改操作可能發生在"x"乘2之前,也有可能發生在之後。
語句b)中,對"x"的可能修改操作可能發生在"x"乘2之前,也有可能發生在之後。
語句c)中,函式nsef()永遠不能修改"x"的值。
程式設計規範修改舉例
Rule13.5 3415
3415 Right hand operand of '&&' or ' ' is an expression with possible side effects.
僅僅只有'&&'操作符的左運算元為1(真)時,才會執行它的右運算元。僅僅只有' '操作符的左運算元為0(假)時,才會執行它的右運算元。
正因為如此,如果這些操作符的右運算元有副作用,就可能引發混亂。訊息3415用於識別這種情況。
當一個表示式是以下情況時,會產生副作用:
訪問'volatile' 物件
執行自增、自減、賦值或複合賦值操作
執行I/O 操作
呼叫一個執行上面任意操作的函式
程式設計規範修改舉例