gcc和vc編譯器區別

gcc編譯器的功能強大,支持的語法也非常靈活,給我們在編程時帶來了非常大的方便,也給移植代碼時帶來了一定的難度。 

1 聲明64位數據類型:
gcc: long long
vc: __int64 

2 switch語法中的case語句:
gcc: case '0' ... '9'
vc: case 0:
     case1:
      ...

3 寄存器變量的作用範圍:
gcc: 可以把register變量聲明爲全局或局部的
vc: 只能是局部變量

4 有符號和無符號整形:
gcc: 在常量數字後面加LL或ULL,例如:
無符號:0xffffffffffffffffULL
有符號:0xffffffffffffffffLL
vc: 在常量數字前加強制轉換。例如:
無符號:(uint64_t)0xffffffffffffffff

5 宏變參
gcc: #define AAA(x...) 
vc: 不支持,在實際中碰到此類問題時只能根據代碼分析實際情況將它分解成若干個宏

6 對數組中指定元素的初始化:
gcc: static int array[100] = { 
      [10] = 10, /* array[10] = 10; */
      [20] = 20, /* array[20] = 20; */
}
功能:通過這種方法,可在數組的聲明當中就初始化指定元素的值,除了arrar[10]和array[20]外,其餘元素會自動初始化爲默認值,這給我們帶來了一種很簡捷的辦法,這功能是不是很酷?

vc: 不支持,只能通過在指定元素前後填充0或另外寫一個初始化函數來實現。如初始化函數可以這樣寫:
void init_array()
{
array[10] = 10;
array[20] = 20;
}

7 結構體的對齊:
 先解釋一下如下幾個屬性關鍵字的含義:
1    屬性 packed: 用於變量和類型,表示變量或結構域時使用最小可能的對齊,用於枚舉、結構或聯合類型時表示該類型使用最小的內存。
2    屬性 aligned:用於變量、結構或聯合類型,指定變量、結構域、結構或聯合的對齊量,以字節爲單位。                     
3   屬性 noreturn:用於函數,表示該函數從不返回。這可以讓編譯器生成稍微優化的代碼,最重要的是可以消除不必要的警告信息比如未初使化的變量。
4   屬性 unused:用於函數和變量,表示該函數或變量可能不使用,這個屬性可以避免編譯器產生警告信息。
      如上這些關鍵字在gcc和vc中都是相對應的,只是使用的方法不一樣。注意:vc必須裝了service pack補丁後才支持。  

gcc:
struct __attribute__((packed)) st_syment
{
...
}

vc:
#pragma pack(push,1)
struct st_syment
{
...
}
#pragma pack(pop)
表示在這個結構體的元素是按字節對齊的。

gcc: __attribute__((aligned(16)))
vc: __declspec(align(16))
表示創建此結構體實例時按16字節對齊。

gcc: __attribute((noreturn))
vc: __declspec(noreturn)
表示此函數不需要返回。

8 得到當前函數的返回地址,就是這個函數被調用處的下條指令地址。例如:
push edx
call _func /* 調用名爲func函數 */
pop edx
而在func()函數中又有這樣一條語句:
void func()
{
... 
retaddr = __builtin_return_address(0); /* 此條語句執行後,retaddr的值應該是上面pop edx指令的地址 */
...
}

gcc: retaddr = __builtin_return_address(0)
vc: __asm { mov eax, [ebp+4] }
     __asm { mov retaddr, eax }
      我們知道,cpu執行一條指令時,eip總是指向下一條指令地址的,在調用一個函數前,就會先把eip入棧,以便函數返回後繼續執行後面的指令,也就是說,在進入函數之前,棧頂(esp)的值就是eip了,所以我們就可以根據這個思路來解決。在vc編譯後生成的彙編代碼中,每個函數頭部都有這樣兩條指令:
      push ebp
      mov ebp, esp
     就是將原來的esp放到ebp中了,加上前面一句push ebp,而壓棧的順序又是由高到低的,所以[ebp+4]就等於函數被調之前的eip。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章