2013-03-22 43 views
-3

我有一個簡單而愚蠢的代碼片段來分析。 它在本質上進行類似:鏈接分配和隱式轉換的優先級

a = b = c; 

但類型是非常棘手的。
在一個地方,我有:

int a,c; 
unsigned int b; 

在其他地方,我有:

int a; 
unsigned int b,c; 

如果編譯器解釋A = B,然後我轉換一個unsigned int到int
OK,在2補碼上,無論如何,這種轉換是無效的
但是這樣的轉換可能會溢出,這將是UB,是不是?
而在這種情況下,編譯器有一個許可證來推測我不依賴UB,因此最終可以認爲a> = 0,並且不再進行進一步的測試if(a<0) blah...它是對的嗎?

在這種情況下,兩段代碼都會導致相同的行爲。

如果編譯器解釋a = c,我認爲這是做什麼,如果我上面的UB分析是正確的,那麼這兩段代碼可能會給出不同的結果。

因此,如何在這些表達解釋a=ba=c,或者換言之在這種情況下,可以這樣的(a<0)分支被消除,只有一個,兩個或無?

最後一點,我的確切情況是內聯函數的返回值,但我認爲它不會超出上述結論,對吧?

static inline int a1(unsigned int *b,unsigned int c) {return *b=c;} 
static inline int a2(unsigned int *b,int c) {return *b=c;} 
+1

1.代碼中沒有強制轉換。 2.你發佈的函數除了拋出語法錯誤之外別無其他。 – 2013-03-22 22:47:16

+0

@ H2CO3哎呀,謝謝,我的錯誤 – 2013-03-22 22:51:14

回答

1
a = b = c; 

是相同

a = (b = c); 

這是你的兩個例子有效。

但是這樣的演員陣容會溢出,這會是UB,是不是?

沒有強制轉換,而是從一種類型到另一種類型的隱式轉換。 將unsigned int類型的值轉換爲int時,如果unsigned int值在int中不可表示,則轉換的結果或者是實現定義的,或者是實現定義的行爲信號引發的。嚴格地說,這仍然不是溢出,這不是未定義的行爲。

+0

這可能會引發一個有符號整數溢出異常。不過,大多數CPU不會這樣做。 – 2013-03-22 22:52:11

+0

你的意思是說'int a = 1U +(unsigned int)(INT_MAX);'總是定義良好,並且編譯器永遠不會消除以下'if(a <0)'? – 2013-03-22 22:54:48

+0

@Loadmaster讓我重新修改這個 – ouah 2013-03-22 22:54:54