1. 程式人生 > >GCC優化與返回Local Variables

GCC優化與返回Local Variables

先看程式碼:

char*  func(int a)
{
   char xxxx[ 20 ] = "func test return";

   return xxxx;
}
//為了節約版面,這裡省略main函式的程式碼

趕緊很明顯是錯誤的,返回棧上的區域性變數。函式返回的時候變數已經不存在了!這樣編譯:

gcc xxx.c
有如下警告資訊:
return.c: In function ‘func’:
return.c:21: warning: function returns address of local variable

返回結果“列印”是正確的!當然我還是懷疑結果的正確性!再寫測試程式碼如下:

char*  func(int a)
{
   char xxxx[ 20 ] = "func test return";

   return xxxx;
}

char*  func1(int a)
{
   char *xxxx="func1 test return";

   return xxxx;
}

int main(int argc, char *argv[])
{
   char *ptr = func(100 );
   printf( "first  = %s\n", ptr);
   printf( "%s\n", func1(90 ));
   printf( "second = %s\n"
, ptr); return 0; }

這個測試用列是有特別用意的,呼叫函式func和func1的棧結構是一樣的。結果輸出是錯誤的!為什麼呢?其實想象也是明白的,函式呼叫肯定是不會出錯,只是返回了棧上的地址而已,操作返回的地址才會出錯。這也是指標的特性!說到這裡是否和GCC優化還是沒有扯傻瓜關係,下面我們加入優化選項觀察!這樣編譯:

gcc -O3 xxx.c
有如下警告資訊:
return.c: In function ‘func’:
return.c:21: warning: function returns address of local variable

返回結果是正確的!對比兩總編譯方式的彙編:第一種:

0000000000400534 <func>:
  400534:       55                      push   %rbp
  400535:       48 89 e5                mov    %rsp,%rbp
  400538:       89 7d dc                mov    %edi,-0x24(%rbp)
  40053b:       c7 45 e0 66 75 6e 63    movl   $0x636e7566,-0x20(%rbp)
  400542:       c7 45 e4 20 74 65 73    movl   $0x73657420,-0x1c(%rbp)
  400549:       c7 45 e8 74 20 72 65    movl   $0x65722074,-0x18(%rbp)
  400550:       c7 45 ec 74 75 72 6e    movl   $0x6e727574,-0x14(%rbp)
  400557:       c7 45 f0 00 00 00 00    movl   $0x0,-0x10(%rbp)
  40055e:       48 8d 45 e0             lea    -0x20(%rbp),%rax
  400562:       c9                      leaveq
  400563:       c3                      retq

第二種:

0000000000400540 <func>:
   400540:       48 8d 44 24 d8          lea    -0x28(%rsp),%rax
   400545:       c3                      retq   
   400546:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
   40054d:       00 00

第二種直接把函式inline了,所以列印的結果是正確的!