通过指针进行迭代和通过索引进行迭代是否产生相同代码

原创 2005年03月04日 11:31:00

编译器对通过指针进行迭代和通过索引进行迭代是否产生相同代码?问题来自于《The C++ Program Language》第五章习题8。

 

测试代码如下:(采用vc.net向导自动生成控制台应用程序)

#include "stdafx.h"

void fi (char v[]) // line 5

{

    for (int i = 0; v[i] != 0; ++i) {

        v[i] += 1;

    }

}

 

void fp (char v[]) // line 12

{

    for (char *p=v; *p != 0; ++p) {

         *pa += 1;

    }

}

 

int _tmain(int argc, _TCHAR* argv[]) // line 19

{

    char a[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g' , 'h'};

    fp (a);

    fi (a);

    return 0;

}

 

vc++7.net上使用参数FA(仅列出程序集),产生的汇编代码如下(未优化):

 

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

 

       TITLE       ./5_8.cpp

       .386P

include listing.inc

... ... ... ...

INCLUDELIB LIBCD

INCLUDELIB OLDNAMES

 

PUBLIC       ?fi@@YAXQAD@Z                              ; fi,函数fi的代码开始

EXTRN       __RTC_InitBase:NEAR

EXTRN       __RTC_Shutdown:NEAR

;      COMDAT rtc$IMZ

; File d:/vsproject/5_8/5_8.cpp

rtc$IMZ       SEGMENT

__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase

rtc$IMZ  ENDS

;      COMDAT rtc$TMZ

rtc$TMZ       SEGMENT

__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown

; Function compile flags: /Odt /RTCsu /ZI

rtc$TMZ ENDS

;       COMDAT ?fi@@YAXQAD@Z

_TEXT       SEGMENT

_i$10435 = -8                                    ; size = 4

_v$ = 8                                             ; size = 4

?fi@@YAXQAD@Z PROC NEAR                                 ; fi, COMDAT

; Line 6

       push       ebp

       mov ebp, esp

       sub  esp, 204                       ; 000000ccH

       push       ebx

       push       esi

       push       edi

       lea   edi, DWORD PTR [ebp-204]

       mov ecx, 51                                ; 00000033H

       mov eax, -858993460                         ; ccccccccH

       rep stosd

; Line 7  // ********************************

       mov       DWORD PTR _i$10435[ebp], 0

       jmp       SHORT $L10436

$L10437:

       mov eax, DWORD PTR _i$10435[ebp]

       add  eax, 1

       mov       DWORD PTR _i$10435[ebp], eax

$L10436:

       mov eax, DWORD PTR _v$[ebp]

       add  eax, DWORD PTR _i$10435[ebp]

       movsx       ecx, BYTE PTR [eax]

       test  ecx, ecx

       je       SHORT $L10434

; Line 8

       mov eax, DWORD PTR _v$[ebp]

       add  eax, DWORD PTR _i$10435[ebp]

       movsx       ecx, BYTE PTR [eax]

       add  ecx, 1

       mov edx, DWORD PTR _v$[ebp]

       add  edx, DWORD PTR _i$10435[ebp]

       mov BYTE PTR [edx], cl

; Line 9

       jmp       SHORT $L10437

$L10434:

; Line 10

       pop  edi

       pop  esi

       pop  ebx

       mov esp, ebp

       pop  ebp

       ret   0

?fi@@YAXQAD@Z ENDP                                  ; fi

_TEXT   ENDS

 

PUBLIC       ?fp@@YAXQAD@Z                                  ; fp,函数fp的代码开始

; Function compile flags: /Odt /RTCsu /ZI

;       COMDAT ?fp@@YAXQAD@Z

_TEXT       SEGMENT

_p$10442 = -8                                          ; size = 4

_v$ = 8                                             ; size = 4

?fp@@YAXQAD@Z PROC NEAR                                 ; fp, COMDAT

; Line 13

       push       ebp

       mov ebp, esp

       sub  esp, 204                       ; 000000ccH

       push       ebx

       push       esi

       push       edi

       lea   edi, DWORD PTR [ebp-204]

       mov ecx, 51                                ; 00000033H

       mov eax, -858993460                         ; ccccccccH

       rep stosd

; Line 14       // ******************************

       mov eax, DWORD PTR _v$[ebp]

       mov       DWORD PTR _p$10442[ebp], eax

       jmp       SHORT $L10443

$L10444:

       mov eax, DWORD PTR _p$10442[ebp]

       add  eax, 1

       mov       DWORD PTR _p$10442[ebp], eax

$L10443:

       mov eax, DWORD PTR _p$10442[ebp]

       movsx       ecx, BYTE PTR [eax]

       test  ecx, ecx

       je       SHORT $L10441

; Line 15

       mov eax, DWORD PTR _p$10442[ebp]

       movsx       ecx, BYTE PTR [eax]

       add  ecx, 1

       mov edx, DWORD PTR _p$10442[ebp]

       mov BYTE PTR [edx], cl

; Line 16

       jmp       SHORT $L10444

$L10441:

; Line 17

       pop  edi

       pop  esi

       pop  ebx

       mov esp, ebp

       pop  ebp

       ret   0

?fp@@YAXQAD@Z ENDP                               ; fp

_TEXT   ENDS

 

PUBLIC  _main

EXTRN       @_RTC_CheckStackVars@8:NEAR

EXTRN       __RTC_CheckEsp:NEAR

; Function compile flags: /Odt /RTCsu /ZI

;      COMDAT _main

... ... ... ...

END

注意上面Line8Line15前后的汇编语句,就是一模一样的。也就是说,在没有任何优化的情况下,通过指针进行迭代和通过索引进行迭代将产生相同代码。

如果进行全面的优化,结果会怎么样呢?对同一个文件,在vc7.net采用RELEASE,打开全局优化,产生的汇编代码如下。可以看到,两个函数的代码仍然是相同的。

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

 

       TITLE       ./5_8.cpp

       .386P

include listing.inc

... ... ... ...

INCLUDELIB LIBC

INCLUDELIB OLDNAMES

 

PUBLIC       ?fi@@YAXQAD@Z                              ; fi,函数fi的代码开始

; Function compile flags: /Ogty

;       COMDAT ?fi@@YAXQAD@Z

_TEXT       SEGMENT

_v$ = 8                                             ; size = 4

?fi@@YAXQAD@Z PROC NEAR                                 ; fi, COMDAT

; File d:/vsproject/5_8/5_8.cpp

; Line 7

       mov eax, DWORD PTR _v$[esp-4]

       cmp BYTE PTR [eax], 0

       je       SHORT $L9624

       npad       7

$L9622:

; Line 8

       inc   BYTE PTR [eax]

       mov cl, BYTE PTR [eax+1]

       inc   eax

       test  cl, cl

       jne       SHORT $L9622

$L9624:

; Line 10

       ret   0

?fi@@YAXQAD@Z ENDP                                  ; fi

_TEXT   ENDS

 

PUBLIC       ?fp@@YAXQAD@Z                                  ; fp,函数fp的代码开始

; Function compile flags: /Ogty

;       COMDAT ?fp@@YAXQAD@Z

_TEXT       SEGMENT

_v$ = 8                                             ; size = 4

?fp@@YAXQAD@Z PROC NEAR                                 ; fp, COMDAT

; Line 14

       mov eax, DWORD PTR _v$[esp-4]

       cmp BYTE PTR [eax], 0

       je       SHORT $L9631

       npad       7

$L9629:

; Line 15

       inc   BYTE PTR [eax]

       mov cl, BYTE PTR [eax+1]

       inc   eax

       test  cl, cl

       jne       SHORT $L9629

$L9631:

; Line 17

       ret   0

?fp@@YAXQAD@Z ENDP                               ; fp

_TEXT   ENDS

 

PUBLIC  _main

EXTRN       ___security_cookie:DWORD

EXTRN       @__security_check_cookie@4:NEAR

; Function compile flags: /Ogty

;      COMDAT _main

... ... ... ...

END

相关文章推荐

内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:通过指针进行迭代和通过索引进行迭代是否产生相同代码
举报原因:
原因补充:

(最多只允许输入30个字)