Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Como a função void não possui retorno não posso usar return 0 pra encerrar. Há algum método alternativo pra isso?
>
Coloque return;.
Mas isso está estranho... Como é a função?
Eu não tenho uma função ainda, só estava pensando sobre isso, mas percebi que estou equivocado. Eu posso usar return em uma função void?
Sim. você pode. Mas só se faz isso quando o ponto de retorno é diferente do final da função.
Imagine que você tenha uma função cujo tipo de retorno é void que faz algum processamento maluco em um uma sequência de inteiros (passada como ponteiro como argumento da função). E por algum motivo, essa função precisa verificar algumas condições antes de fazer a alteração na sequência de inteiros.
A coisa ficaria mais ou menos assim, usando o return vazio:
void processa_inteiros(int ** seq) {
if (....) return; // Condição especial na qual o processamento não deve ser realizado.
// Processamento da sequência.
}
Isso poderia ser reescrito da seguinte forma:
void processa_inteiros(int ** seq) {
if (/*Condição para que o processamento ocorra */) {
// Processamento da sequência.
}
}
Entrando nos detalhes de baixo nível:
int main(void) {
return 0;
}
Em Assembly, o main (aqui no meu pc) tem essa cara:
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl $0, %eax
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
Esses pushl, movl,popl são operações na pilha de argumentos. O *return 0* está traduzido ali,basicamente, em 3 instruções:
movl $0, %eax
popl %ebp
ret
A grosso modo, a instrução ret é a responsável pelo retorno da execução do programa ao ponto anterior, ou seja, a partir da última chamada. No caso de funções chamadas no main, ele segue p/ o endereço da próxima instrução a ser executada. No caso do main, o programa acaba retornando para o sistema operacional.
void f() {}
int main(void) { return 0; }
A função f em Assembly:
f:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endprocConsidere o seguinte programa inútil:
#include <stdio.h>
void f(int a) { if(a==4) return; puts("Diferente de 4");}
int main(void) { return 0; }
f:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
cmpl $4, 8(%ebp)
jne .L2
jmp .L1Aquele cmpl $4, 8(%ebp) é o if. Caso ele seja falso, ou seja, a!=4, o fluxo da execução é transferido para o código na seção .L2 (a chamada à função puts, seguindo a instrução jne .L2). Caso a == 4, a instrução jmp .L2 é executada, que contém a indicação de retorno ret. Repare que mesmo que a seção .L2 seja executada, o fluxo de execução continua seguindo em frente, atingindo a seção .L1 e executando a instrução ret.
Se retirarmos o return explícito (if(a!=4) puts("Diferente");):
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
cmpl $4, 8(%ebp)
je .L1
movl $.LC0, (%esp)
call putsOu seja, toda função tem uma instrução ret; o return explícito na função void "apenas" cria mais pontos de desvio no código (considerando aqui, Assembly).
Coloque return;.
Mas isso está estranho... Como é a função?