Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Pulse

Encerrar função void

Recommended Posts

Como a função void não possui retorno não posso usar return 0 pra encerrar. Há algum método alternativo pra isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

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?

Compartilhar este post


Link para o post
Compartilhar em outros sites

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_endproc 

Repare que mesmo sem escrever o return, há um ret final p/ que o fluxo retorne ao ponto de chamada.

Considere 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	.L1
.L2:
	movl	$.LC0, (%esp)
	call	puts
.L1:
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc

Aquele 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	puts
.L1:
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc

Ou 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).

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.