C - uso do return em função void

Programação C em geral

Moderadores: 51, guest2003

C - uso do return em função void

Mensagempor RobL » 13 Abr 2010 10:11

Alguem tem uma posição mais clara para o uso do return em função void?
O seu uso seria por rigor, para diagnóstico, ou para evitar algum outro problema que desconheço ?

Código: Selecionar todos
void nome(void)
{
/*corpo da função*/
return; /*este return aqui. Para que serve de fato ? */
}


Exemplo encontrado num artigo do msdn da Microsoft
Código: Selecionar todos
void draw( int I, long L );
long sq( int s );
int main()
{
    long y;
    int x;

    y = sq( x );
    draw( x, y );
    return();
}

long sq( int s )
{
    return( s * s );
}

void draw( int I, long L )
{
    /* Statements defining the draw function here */
    return;
}


comentário no msdn:
The draw function is declared as a void function and does not return a value. An attempt to assign the return value of draw would cause a diagnostic message to be issued.


Aqui parece que o uso do return é para causar uma menssagem de diagnóstico. Penso que isto vai depender do compilador.

No livor do Kernighan & Ritchie (segunda edição pag 61)

The calling function is free to ignore the returned value. Furthermore, there need to be no
expression after return; in that case, no value is returned to the caller. Control also returns to
the caller with no value when execution ``falls off the end'' of the function by reaching the
closing right brace. It is not illegal, but probably a sign of trouble, if a function returns a value
from one place and no value from another. In any case, if a function fails to return a value, its
``value'' is certain to be garbage.


Não entendí especialmente essa parte:
It is not illegal, but probably a sign of trouble, if a function returns a value
from one place and no value from another.

Enfim, devemos colocar return no final de uma função void ? Por que ?
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor ivan » 13 Abr 2010 11:21

Robl wrote: from Kernighan...
...
It is not illegal, but probably a sign of trouble, if a function returns a value from one place and no value from another.
...


É exatamente o que está escrito. Imagine uma função onde em um ponto se use um return sem valor e, na mesma função, utilize-se return com valor em outro ponto. Não é ilegal mas um perigo em potencial.

Robl wrote: from Kernighan...

Control also returns to the caller with no value when execution ``falls off the end'' of the function by reaching the closing right brace


Colocar o return, ou não, em uma função void(procedure) é dispensável.
EU prefiro colocá-lo sempre! Mesmo qdo a função é uma procedure, apenas por padronização.
"A mente que se abre a uma nova idéia jamais volta ao seu tamanho original." (Albert Einstein).
Avatar do usuário
ivan
Word
 
Mensagens: 618
Registrado em: 12 Out 2006 21:27

Re: C - uso do return em função void

Mensagempor barboza » 13 Abr 2010 11:27

RobL escreveu:

Não entendí especialmente essa parte:
It is not illegal, but probably a sign of trouble, if a function returns a value
from one place and no value from another.




Bem, se é para retornar algum valor, deve fazer isso em qualquer posição de return que tenha. O problema é se retorna algo em uma posição e em outra não.

Uso return em funções do tipo void, somente como saída alternativa no meio da função, não no fim.
Ex.:

Código: Selecionar todos

void p_xxxx(void)
{

   if (not_ready)
   {
      return;
   }
   else
   {
      do something
               ......
   }
}

Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor msamsoniuk » 13 Abr 2010 12:10

a funcao main eh chamada por outra funcao e ela espera que main retorne um int:

status = main(argc, argv, argp);

se vc faz main retornar void, vc obtem um belo stack underflow e de quebra um status de operacao invalido que depende do valor aleatorio que estiver na stack naquela hora! e tb eh sempre bom ter em mente o q vai retornar, normalmente retorna-se 0 para sucesso e um numero de 1 a n para indicar diferentes erros ocorridos :)

agora, se for uma funcao outra qualquer e vc nao pesca um retorno quando chama, deve usar void justamente para nao ficar deixando lixo na stack. tem que pensar que o compilador nao fica monitorando a stack, bem pq vc pode fazer coisas diferentes e linkar no final, nao deixando margem nem para o compilador alertar sobre a falha :)
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor RobL » 13 Abr 2010 15:33

Primeiramente, muito obrigado a todos que responderam.

Como parece não haver nada de especial, oculto, no return ao final de uma função com retorno void, ou seja, sem retorno, passarei a seguir a prática de colocá-lo ao final da função ( return ; ). Pelo menos no C99 não tem problema.
Farei isto para reforçar visualmente o término dessas funções.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor barboza » 13 Abr 2010 15:45

RobL escreveu:Primeiramente, muito obrigado a todos que responderam.

Como parece não haver nada de especial, oculto, no return ao final de uma função com retorno void, ou seja, sem retorno, passarei a seguir a prática de colocá-lo ao final da função ( return ; ). Pelo menos no C99 não tem problema.
Farei isto para reforçar visualmente o término dessas funções.


Se usar a indentação, a chave fechada alinhada a esquerda já te indica o fim da função. rs
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor andre_luis » 13 Abr 2010 16:52

Olha...eu já notei o uso do return como uma saída prematura da cadeia de execução aninhada, tal como um break é utilizado para sair de uma instrução de loop.

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor RobL » 13 Abr 2010 17:29

A questão aqui é o porque do uso do return em funções void. Parece haver algo com análise de semântica e sintaxe.

Como o C é muito aberto e sem muitos testes, procuro ser o mais purista possível (não consigo ser).

Por exemplo, eu não usaria return para sair de um looping dentro de uma função, só por rigor. Como disse não é bom arriscar em C.
Usaria primeiro o break e no final return.
Não vai dar diferença "talvez" na maioria dos casos. Mas em C cautela é bom. Para quem quer portabilidade tem que ter rigor.

Barboza:
A tempos venho observando um monte de caras sérios por aí que usa o return ao final de uma função void. Como não encontrei nehuma explicação para tal, vou dar uma de macaco (se bem que eles tem demonstrado maior inteligência que a minha, peço desculpas aos ancestrais). Resolví colocar return, além do uso da identação. Seguir a linha do Ivan. Me pareceu sinalizar melhor o fim da f() :wink:
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor msamsoniuk » 13 Abr 2010 21:58

eh soh olhar o que o compilador gera no assembler... normalmente return sem valor nenhum resulta em uma simples instrucao de retorno, em oposicao a instrucao return com valor, que empilha um valor e depois faz o retorno.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor vtrx » 13 Abr 2010 23:05

void p_xxxx(void)
{

if (not_ready)
{
return;
}
else
{
do something
......
}
}

Nesse seu exemplo,usando o 'return' voce não precisa do 'else'.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor barboza » 14 Abr 2010 07:49

vtrx escreveu:
void p_xxxx(void)
{

if (not_ready)
{
return;
}
else
{
do something
......
}
}

Nesse seu exemplo,usando o 'return' voce não precisa do 'else'.



Este foi um exemplo, mas na pratica não faz diferença lógica nem de ocupação em código, pois o teste e o jump vai exisitir do mesmo jeito.


Código: Selecionar todos
void p_xxxx(void)
{

   if (not_ready)
   {
      return;
   }

   do something
   ......
}
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor RobL » 14 Abr 2010 11:27

Já que ampliaram o tópico, vou aproveitar para chamar atenção para certos detalhes:

A preocupação desta questão, tanto do uso do retorno na função void, como outros usos não padrão, como sair de um switch dentro de uma função por um retorno, está ligada ao processo de análise de semântica e sintaxe.
Não é o caso de usar um return, para se obter um código menor.
A razão do uso do rigor é exatamente quando se usa um bloco mais complexo com várias partes aninhadas. É aí que pode dar problema entre (ou de) semântica e (ou de) sintaxe.
Não tenho um trecho de código, como exemplo, para mostrar isto, mas todos nós já tivemos problema com um bloco que dá um certo erro ou aviso e não entendemos por que. Resolvendo por tentativa e erro, mudando um detalhe que sempre fizemos mas não funcionou naquele bloco, acaba compilando sem erro.
Este é um caso de possível desacordo entre semântica e sintaxe.

A probabilidade destes problemas aparecerem, normalmente está na conjugação com um grupo de código e até blocos e não num pequeno e simples bloco.
Aí, talvez, pode este não ser o caso, pois eu não tenho conhecimento para afirmar isto, mas manter o return sempre ao final de todas as funções (e outros procedimentos padrão), pode ser o caso, para evitar avisos e erros, em relacionamento de trechos de código que estão sendo analisados pelo compilador.
Pode até ser o caso de não dar erro sem otimização e erro com otimização, pois neste caso entra o relacionamento entre blocos.

Aproveitando, sugestão:
Daí, infiro, se um bloco não quiser compilar, tente usar o padrão recomendado pela linguagem.
A maior dificuldade é que o compilador poderá informar um erro em um bloco mas o problema está em outro trecho do programa devido ao interrelacionamento do código.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor fabim » 14 Abr 2010 11:40

hehe, ja vi um cumpadi quase morrer colocando return pra tudo quanto é lado, por usar statements de teste, e return em cada um, e não saber pra que servia o "continue;"
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor barboza » 14 Abr 2010 12:50

fabim escreveu:hehe, ja vi um cumpadi quase morrer colocando return pra tudo quanto é lado, por usar statements de teste, e return em cada um, e não saber pra que servia o "continue;"



"continue" pra mim é igual "goto", tem na linguagem, mas não uso.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor tcpipchip » 14 Abr 2010 17:41

Exemplo de baixaria

unsigned char result;

void main()
{

result =calcula(2,3);
while(1);
}

void calcula(unsigned char v1,v2)
{
return(v1+v2);
}

Falando em pilha

a funcao

calcula(2,3);
*

Joga 2 e 3 na pilha

2
3

e depois o endereço de retorno (pq é um call)

2
3
*

a Funcao acessa a pilha e pega o valor 2 e 3 e processa...e acredito eu que jogue em um REGISTRADOR da RESPOSTA se for escalar...nao poe nada mais na pilha...

ai retira da pilha o endereço de retorno, volta, mas descarrega mais 2 dados da pilha...

Ou seja, acho que nao dá UNDERFLOW

TCPIPCHIP
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Próximo

Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x