Je devine ici, mais il pourrait être possible de les faire manuellement.
Le premier modèle de remplissage utilise la récursivité pour remplir un tampon. La seconde utilise une récursivité de queue artisanale pour faire la même chose.
Cela peut être mauvais pour une raison quelconque, donc je suggère qu'il est à utiliser avec prudence.
par ex.
#include <stdio.h>
template <class myType>
// fill a buffer with n v's
void fill(myType *p , int n , myType v){
if (n <= 0) return;
*p = v;
fprintf(stderr , "[%x] = %d\n" , (unsigned) p , *p);
fill(p+1 , n-1 , v);
}
template <class myType>
// fill a buffer with n v's
void fillTail(myType *p , int n , myType v){
tail:
if (n <= 0) return;
*p = v;
fprintf(stderr , "[%x] = %d\n" , (unsigned) p , *p);
// hand crafted tail call
p++;
n--;
goto tail;
}
int main(){
int buf[100];
int v = 12;
fill(buf , 10 , v);
for (int i=0; i<10 ; i++){
fprintf(stderr , "[%d] = %d\n" , i , buf[i]);
}
v = 13;
fill(buf , 10 , v);
for (int i=0; i<10 ; i++){
fprintf(stderr , "[%d] = %d\n" , i , buf[i]);
}
}
Edit:
Bonne idée d'ajouter l'assembleur. J'ai changé certaines étiquettes pour le rendre plus clair. J'ai simplement utilisé g++ file.cpp
pour compiler et g++ -S file.cpp
pour obtenir l'assembleur.
fill:
pushl %ebp
LCFI0:
movl %esp, %ebp
LCFI1:
subl $24, %esp
LCFI2:
cmpl $0, 12(%ebp)
jle L4
movl 8(%ebp), %edx
movl 16(%ebp), %eax
movl %eax, (%edx)
movl 12(%ebp), %edx
decl %edx
movl 8(%ebp), %ecx
addl $4, %ecx
movl 16(%ebp), %eax
movl %eax, 8(%esp)
movl %edx, 4(%esp)
movl %ecx, (%esp)
call fill
L4:
leave
ret
fillTail:
pushl %ebp
LCFI3:
movl %esp, %ebp
LCFI4:
subl $8, %esp
LCFI5:
jmp L6
L10:
movl 8(%ebp), %edx
movl 16(%ebp), %eax
movl %eax, (%edx)
addl $4, 8(%ebp)
leal 12(%ebp), %eax
decl (%eax)
L6:
cmpl $0, 12(%ebp)
jg L10
L9:
leave
ret
Quelles options g ++ avez-vous utilisées? Mon code sans options n'a pas fait l'optimisation de la queue-appel. – philcolbourn
@philcolbourn g ++ -g -O2 -Wall -pedantic tr.cpp –
@Neil Butterworth Merci. Et pour obtenir la source inline avec l'assembleur? – philcolbourn