爲什麼不是這段代碼導致y == 0x100
?++((無符號)x)的意外結果,x是uint8_t?
uint8_t x = 0xff;
unsigned y = ++((unsigned)x);
檢查出來爲自己在這裏:http://codepad.org/dmsmrtsg
爲什麼不是這段代碼導致y == 0x100
?++((無符號)x)的意外結果,x是uint8_t?
uint8_t x = 0xff;
unsigned y = ++((unsigned)x);
檢查出來爲自己在這裏:http://codepad.org/dmsmrtsg
您發佈的代碼是無效的形式來看C語言的點。 C中任何投射的結果都是一個右值。它不能用作++
的參數。運算符++
需要一個左值參數。即表達式++((unsigned) x)
在標準C語言中是不可編譯的。
你實際上在這種情況下,觀察什麼是GCC的「廣義左值」擴展
http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Lvalues.html
每即擴展(和違反標準C),流延應用於左值產生左值。當您嘗試在結果「廣義」左值中寫入某些內容時,正在寫入的值將被轉換兩次:首先將其轉換爲顯式類型轉換指定的類型,然後將中間結果再次轉換爲接收者的類型目的。最終的結果被放入收件人對象。
例如,如果你的x
你
(unsigned) x = 0x100;
將通過GCC實際解釋爲
x = (uint8_t) (unsigned) 0x100;
和x
終值將是0
。
而這正是你的例子中發生的情況。在GCC您
++((unsigned) x)
相當於
(unsigned) x = (unsigned) x + 1;
後者又解釋由GCC作爲
x = (uint8_t) (unsigned) ((unsigned) x + 1);
這就是爲什麼你在x
作爲結果得到0
,那就是0
然後被分配到您的y
。
此擴展被稱爲已棄用 GCC文檔。
要啓動這不是有效的C代碼,我不知道你是怎麼得到它來編譯,但您的鏈接確實顯示輸出,所以我會試着解釋這一個主要假設發生了什麼依據:
我想這條線unsigned y = ++((unsigned x));
第二unsigned
是由編譯器下降,因此爲什麼你能夠建立。
因此,假設...
uint8_t x = 0xff; // 8 bit value, max is 255(10) or 0xFF(16)
unsigned y = ++((unsigned)x);
現在x
已經是它的類型的最大值。你想知道爲什麼我們通過++
+1,y
沒有得到0x100
的價值。
x
是8位,類型化它不會改變它是8位的事實。所以,當我們說:
++x
我們遞增x
(x=x+1
)。因此,我們有一個無符號的8位值,在最大和把它加1,現在它纏到0。所以y
,將會獲得0
如果你想要這個工作,你可以這樣做:
int main(void)
{
unsigned char x = 0xFF; //I'm using char because it's 8 bit too
unsigned int y = 1+x; //no need to typecast, we're already unsigned
printf("%#x %#x\n", x, y);
return 0;
}
現在你會得到的預期值(x==0xFF
和y==0x100
)
試試這個:
uint8_t x = 0xff;
unsigned y = ((unsigned)x) + 1;
它會出來,你實驗值因爲(unsigned) x
現在是雙字節值0x0100
。
現在試試這個:
uint8_t x = 0xff;
++x;
的周圍0xff
餘套0x00
值。
我把一些小小的透明代碼放入你的摘錄中,它解釋了一切。
#include <stdio.h>
#include <stdint.h> // not needed
int main(void) {
uint8_t x = 0xff;
printf("%d\n", sizeof(x));
unsigned y = ++((unsigned)x);
printf("%d\n", sizeof(y));
printf("0x%x\n", y);
printf("%d\n", sizeof(y));
return 0;
}
和輸出
1 // size of x
4 // size of y before computation
0x100 // computed value of y from your code
4 // size of y after computation
注意到的第一件事是,sizeof(y)
保持跨越計算不變。
從輸出,
uint8_t
= 1字節unsigned
= 4字節當你用C做一個演員,把它作爲realloc
隱式調用它說:「藉此數據,我從它的塊,增加(或減少),其在內存中的大小尺寸有我想投它,然後在新的塊返回相同的數據。
而且從我方第從unsigned
將有足夠的空間來適應單字節操作的計算結果。需要左值的增量operand`:
重新explainng你的代碼的字節層次的細節,
x = 11111111 = 0xff (in a byte)
(unsigned)x = 00000000000000000000000011111111 = 0xff (in a word)
++((unsigned)x) = 00000000000000000000000100000000 = 0x100
我得到'錯誤。該代碼無效C(> = 99)。 –
y未簽名...沒有類型? –
@YoussefG。 - 如果您沒有類型 – Mike