Bsico de passagem de parmetros em C++
[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]
para no acontecer certos erros que vi por a...
Em C++ h trs maneiras de passar um parmetro para uma funo, as tradicionais herdadas da linguagem C: valor e ponteiro; alm da novidade: a passagem por referncia. Para ilustrar veja o seguinte exemplo, passar uma estrutura de dados “grande” (neste caso aproximadamente 10 kilobytes) para uma funo:
#include<iostream> #include <string.h>
using namespace std;
struct Big { char text[10000]; int id; };
void f1( Big v ) { cout << v.text << endl; cout << “Ox” << hex << v.id << endl; }
void f2( const Big *v ) { cout << v->text << endl; cout << “Ox” << hex << v->id << endl; }
void f3( const Big &v ) { cout << v.text << endl; cout << “Ox” << hex << v.id << endl; }
int main(int /argc/, char * /argv/[]) {
Big *b0 = new Big; Big b1; Big &b2 = b1;
strcpy(b0->text,“asdfg asdfg asdf asdf asdf asdf”); strcpy(b1.text,“azsxd azsxd azsxd azsxd azsxd azsxd”);
b0->id = 0xbc; b1.id = 0xde;
f2( b0 ); /* pointer */ f1( b1 ); /* value */ f3( b2 ); /* reference */ }
Veja o cdigo assembly gerado pelo compilador (g++) para cada um dos trs casos:
1) Ponteiro
mov -0xc(%ebp),%eax
mov %eax,(%esp)
call 0x8048885
2) Valor
movl $0x0,-0x2728(%ebp)
lea -0x2720(%ebp),%eax
mov %eax,-0x272c(%ebp)
jmp 0x8048a36
mov -0x272c(%ebp),%ecx
mov -0x2728(%ebp),%edx
movzbl (%ecx,%edx,1),%eax
mov -0x2728(%ebp),%edx
mov %al,(%esp,%edx,1)
addl $0x1,-0x2728(%ebp)
cmpl $0x2714,-0x2728(%ebp)
jb 0x8048a16
call 0x80488fe
3) Referncia
mov -0x8(%ebp),%eax
mov %eax,(%esp)
call 0x804880c
Talvez seja importante:
- Se voc prefere a sintaxe da intel? Mude no GDB: set disassembly-flavor intel
- No precisa ser muito esperto para ver que a passagem por valor a pior de todas, veja quanto cdigo assembly foi gerado [#fail]
- A passagem por referncia inclusive mais eficiente pois aloca no %ebp (base pointer) [8 bytes ao invs de 12 bytes do ponteiro].
- A passagem por referncia prov a eficincia da passagem por ponteiros com a clareza da passagem por valor.