vc:末尾再帰の最適化はされたけど

※末尾再帰の理解が間違っているので参照しないでください(2015/08/07 12:17)

一応。

#include <stdio.h>

static int sum(int n, int r) {
  if (n == 1)
    return r;

  return sum(n - 1, r + n);
}

int main() {
  printf("%d\n", sum(5, 0));

  return 0;
}
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 

	TITLE	c:\Program Files\Microsoft Visual Studio 9.0\VC\foo.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

; Function compile flags: /Ogtpy
;	COMDAT _sum
_TEXT	SEGMENT
_sum	PROC						; COMDAT
; _n$ = ecx
; _r$ = eax
; File c:\program files\microsoft visual studio 9.0\vc\foo.c
; Line 4
	cmp	ecx, 1
	je	SHORT $LN7@sum
$LL4@sum:
; Line 7
	add	eax, ecx
	dec	ecx
	cmp	ecx, 1
	jne	SHORT $LL4@sum
$LN7@sum:
; Line 8
	ret	0
_sum	ENDP
_TEXT	ENDS
PUBLIC	??_C@_03PMGGPEJJ@?$CFd?6?$AA@			; `string'
PUBLIC	_main
EXTRN	_printf:PROC
;	COMDAT ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
CONST	SEGMENT
??_C@_03PMGGPEJJ@?$CFd?6?$AA@ DB '%d', 0aH, 00H		; `string'
; Function compile flags: /Ogtpy
CONST	ENDS
;	COMDAT _main
_TEXT	SEGMENT
_main	PROC						; COMDAT
; Line 11
	mov	eax, 5
	lea	ecx, DWORD PTR [eax-1]
	call	_sum
	push	eax
	push	OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
	call	_printf
	add	esp, 8
; Line 13
	xor	eax, eax
; Line 14
	ret	0
_main	ENDP
_TEXT	ENDS
END


cl /O2 /FA foo.c
↓だと最適化されなかった。ブロックの中にあるのがまずいのか、「n +...」ってやってるのがまずいのか。

static int sum(int n) {
  if (n == 1) {
    return 1;
  } else {
    return n + sum(n - 1);
  }
}