2009-11-07 63 views
9

我看過'副作用'this website爲什麼「f = f ++」在c中不安全?

但仍不明白爲什麼f = f++被認爲是不安全的?

有人可以解釋一下嗎?

+0

複製(雖然不是很明顯,如果你不這樣做知道答案爲什麼)http://stackoverflow.com/questions/1678519/difference-between-i-and-i – 2009-11-07 01:50:53

+1

還有一個問題,爲什麼「++ i ++」是非法的,但它不可能被搜索到! – 2009-11-07 01:53:03

+3

這個問題明確地問到爲什麼這個構造是不安全的。您引用的問題具有無效的代碼,因此此構造不安全。兩個不同完全有效的問題。 – joshperry 2009-11-07 02:06:32

回答

16

問題是Sequence Points。在這個語句中有兩個操作沒有順序點,所以沒有給語句定義順序,分配是先發生還是增量?

沒有說這是不安全的,它只是不確定的,這意味着不同的實現可能有不同的結果,或者它可以格式化你的硬盤驅動器...

+2

我想大多數人會考慮格式化一個驅動器,造成'f = f ++'的不安全後果。雖然我認爲大多數人認爲'不安全'並不意味着它可能會破壞某些東西,但是你不能依賴它會做什麼。 – 2009-11-07 02:30:45

+0

C和C++標準在整個過程中非常明確地使用術語「未定義行爲」,特別是詳細描述順序點執行順序的部分。我只是用誇張來強調不安全和未定義之間的區別。 – joshperry 2009-11-07 02:57:50

+4

未完成的行爲意味着不安全的代碼 – hasen 2009-11-07 09:45:18

4

使用xx++(或++x)內相同的語句是在C中未定義的行爲。編譯器可以自由地執行任何想要的操作:在執行分配之前或之後增加x。以Ólafur的代碼,它可能會產生f == 5f == 6,這取決於您的編譯器。

4

您提供的文章(cleaned up) link給出了答案。 「C幾乎沒有承諾副作用將在一個表達式中以可預測的順序發生。」這意味着你不知道=和++會以什麼順序出現。它依賴於編譯器。

如果您在同一站點上關注該文章與關於sequence points的文章的鏈接,您會發現編譯器可以優化將數值從寄存器寫入變量的內容和時間。

+0

另有一點澄清 - 它不僅僅依賴於編譯器。編譯器可以做的事情可能根本就沒有意義 - 即使是相同語句的兩個實例(具有相同的'f'起始值)可能產生完全不同的結果。 – 2009-11-07 02:59:38

0

我支持Arthur在這方面的回答。儘管後增加運算符即f ++的實現令人困惑,但它並不被認爲是不安全的。你應該首先理解編譯器是如何解釋它的。在遇到句子終止(;)後立即增加f還是在使用f的值後立即增加。

+1

它是* undefined *,在C標準的意義上。這不是一個「你必須知道編譯器做什麼」的例子。編譯器可以做任何事情,包括爲f賦予一個值,而這個值不對應於你認爲必須產生的原子指令的任何順序。 – 2009-11-07 11:45:58

1

standard

6.5(2)如果一個標量對象上的副作用是相對於相同的標量對象上或者是不同的副作用,或使用相同的標量的值的值計算未測序 對象,行爲是未定義的。如果子表達式的子表達式存在多個允許的排序順序,則如果在任何排序中出現這種不確定的方面效應,則行爲是不確定的。 74)

74)本款呈現不確定的語句表達,如

 
      i = ++i + 1; 
      a[i++] = i; 

同時允許

 
      i = i + 1; 
      a[i] = i; 
相關問題