關於 printf的深入討論

來源:互聯網
上載者:User
 

    int a = 15;

    printf("%d %d\n", ++a, a++);

    老問題了,也沒什麼好說的,但是順序點涉及到參數的情況還沒仔細考慮過,所以分析下其內部原理。

    我本來的考慮是按照 cdecl 壓棧次序,a++ 先壓入,為 15,此後++發生副作用,a 變為 16,然後壓入 ++a,a 先自增,為 17,所以輸出結果為 17 15。雖然心裡忐忑了一下,但也就這樣自欺欺人了一會,用 gcc 驗證無誤,然後 vc6 就給了我一棒子,它的輸出為 16 15。

    說實話參數裡副作用的順序點我沒有研究過,所以導致了這個結果,於是好好看了下他們生產的彙編碼:

    VC6相應彙編代碼:

5:        int a = 15;
00401028   mov         dword ptr [ebp-4],0Fh
6:
7:        printf("%d %d\n", ++a, a++);
0040102F   mov         eax,dword ptr [ebp-4]
00401032   mov         dword ptr [ebp-8],eax
00401035   mov         ecx,dword ptr [ebp-8]
00401038   push        ecx
00401039   mov         edx,dword ptr [ebp-4]
0040103C   add         edx,1
0040103F   mov         dword ptr [ebp-4],edx
00401042   mov         eax,dword ptr [ebp-4]
00401045   push        eax
00401046   push        offset string "%d %d\n" (00422020)
0040104B   mov         ecx,dword ptr [ebp-4]
0040104E   add         ecx,1
00401051   mov         dword ptr [ebp-4],ecx
00401054   call        printf (004010a0)
00401059   add         esp,0Ch

 

    可以看出,在 0x00401038 處,壓入了第三個參數為 15,0x0040103C 處 a++ 的副作用發生,a 變為 16;0x00401045 處壓入第二個參數為 16,直到 0x0040104E 處 ++a 的副作用才發生,輸出結果為 16 15。我感覺這裡的函數參數的逗號分隔字元並不是逗號運算式,所以不是一個順序點,導致 ++a 在這裡的副作用不一定發生,所以此時 vc 沒有增加 a 的值,是不是這樣呢?難道對於函數參數,順序點在函數結束處[待研究]?

    再來看看 gcc 4.3 的情況,以下是同樣程式它的彙編碼:

0x00401146 <main+22>:   movl   $0xf,-0x8(%ebp)
0x0040114d <main+29>:   mov    -0x8(%ebp),%eax
0x00401150 <main+32>:   addl   $0x1,-0x8(%ebp)
0x00401154 <main+36>:   addl   $0x1,-0x8(%ebp)
0x00401158 <main+40>:   mov    %eax,0x8(%esp)
0x0040115c <main+44>:   mov    -0x8(%ebp),%eax
0x0040115f <main+47>:   mov    %eax,0x4(%esp)
0x00401163 <main+51>:   movl   $0x4020a0,(%esp)
0x0040116a <main+58>:   call   0x4011d8 <printf>

    可以看出,在 0x00401150 和 0x00401154 處 a 自增了 2 次,0x00401158 處壓入 printf 的第三個參數為 15,0x0040115f 處壓入第二個參數,而此時經過 0x0040115c,第二個參數已經為 17 了,所以結果為 17 15。

    雖然是支末問題,不用糾纏,但是仍然引出了很多不確定的東西,當是學習了一次吧。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.