mai
31
2010

Básico de passagem de parâmetros em C++

para não acontecer certos erros que vi por aí…

Em C++ há três maneiras de passar um parâmetro para uma função, as tradicionais herdadas da linguagem C: valor e ponteiro; além da novidade: a passagem por referência. Para ilustrar veja o seguinte exemplo, passar uma estrutura de dados “grande” (neste caso aproximadamente 10 kilobytes) para uma função:

#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 código assembly gerado pelo compilador (g++) para cada um dos três 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) Referência

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
  • Não precisa ser muito esperto para ver que a passagem por valor é a pior de todas, veja quanto código assembly foi gerado [#fail]
  • A passagem por referência é inclusive mais eficiente pois aloca no %ebp (base pointer) [8 bytes ao invés de 12 bytes do ponteiro].
  • A passagem por referência provê a eficiência da passagem por ponteiros com a clareza da passagem por valor.

posted in unifei by Tiago Maluta

Follow comments via the RSS Feed | Deixe um comentário | Trackback URL

2 Comments to "Básico de passagem de parâmetros em C++"

  1. Mauricio wrote:

    Muito bom..
    Incrível essa dos 4 bytes a menos.

    Apesar do V. provavelmente gostar muito disso (rs..), acho que realmente é útil saber; principalmente pela sintaxe.

  2. felipe tonello wrote:

    Fala Maluta,
    Gostei de suas considerações finais..

    Parabéns

Leave Your Comment