2009-06-07 46 views
2

考慮這個代碼,VC9不檢測別名:限制-edness與預C99

typedef struct { int x, y; } vec_t; 

void rotate_cw(vec_t const *from, 
       vec_t  *to) 
{ 
     /* Notice x depends on y and vice versa */ 
     to->x = from->y; 
     to->y = -from->x; 
} 

/* ... */ 
vec_t a, b; 
rotate_cw(&a, &b); /* OK, no aliasing */ 
rotate_cw(&a, &a); /* FAIL, aliasing is not detected */ 

最明顯的解決方法是使用一個臨時:

void rotate_cw(vec_t const *from, 
       vec_t  *to) 
{ 
     int temp = from->x; 
     to->x = from->y; 
     to->y = -temp; 
} 

這是標準的行爲嗎?我期待編譯器,除非被告知,否則會假設這兩個指針可能會被別名。

+4

是的,這不是標準的行爲 - 看起來像一個編譯器錯誤,至少在C99和C++中。他們明確允許相互混淆。我不知道C89是怎麼回事,這似乎是你的原因:(但我認爲我在C89閱讀,事情更容許 – 2009-06-07 20:04:35

+0

你期待C爲你照顧一個角落案件?它並沒有這樣做:你期望自己擔心這些細節,這可能是考慮更高級語言的一個原因,但它不是* c中的錯誤:編譯器完全是做什麼的你告訴它 – dmckee 2009-06-07 20:24:32

回答

4

所寫的代碼在C89或C99中完全有效。這是晦澀難懂的,但編譯器無法診斷,因此無法診斷。

如果您在函數的兩個參數上使用了C99和'restrict',那麼如果您的編譯器支持C99,則會出現錯誤。 AFAIK,沒有當前版本的MSVC,但完全支持C99。

0

在C99發明了restrict限定符之前,一些C編譯器包含了優化選項,這些優化選項將指示他們對指針的使用做出某些假設;我見過的這些編譯器手冊明確警告說,這樣的優化是而不是符合標準,並且可能會隨意導致使用某些特定構造的代碼,這些構造的行爲由標準定義,其行爲方式與標準和程序員的意圖。從手冊的角度來看,優化告訴編譯器編譯C的一個子集,它沒有定義在C中定義的某些角落案例的行爲,但是它可以爲這些案例生成更高效的代碼確定了。