Padrão /w3

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Padrão /w3

Mensagem por JoséQuintas »

É muito bom acostumar com esse padrão de programação.
Mas é importante que não fique limitado aos erros de compilação.

Exemplo:

Código: Selecionar todos

procedure main
mvar := space(10)
@ 2, 20 get mvar valid ConteudoOk()
read

function ConteudoOk()
return .not. empty(mvar)
Essa rotina não passa no padrão /w3.
Primeiro porque as variáveis não estão definidas em cada rotina.
Segundo porque a função ConteudoOk() usa uma variável que não conhece.
Mas se acrescentar MEMVAR para a variável mvar, já passa na compilação com /w3.

A intenção do /w3 não é apenas essa.
O certo é que cada rotina conheça as variáveis que usa.
Então, o mais correto seria alterar dois pontos:
Valid ConteudoOk(mVar)
Function ConteudoOk(mVar)

Obs. Poderia ser indicado direto no valid, mas este é só um exemplo do que seria o padrão /w3

Mas mesmo assim... qual vantagem?
Antes de alterar, a rotina ConteudoOk() é totalmente dependente da variável existir na rotina que a chama. Não se pode nem mexer no nome da variável, e se for usada por outra rotina, é obrigatório usar o mesmo nome de variável.
Após alterar, ConteudoOk() se tornou uma função independente, e pode tranquilamente ser modificada, ou usada em qualquer rotina, seja qual for a variável.

É isso que se deve tomar cuidado: não confundir padrão /w3 com apenas evitar erros ao compilar com /w3.

Acontece de vez em quando de digitar errado o nome de uma variável, e só vamos descobrir quando está rodando no cliente.
Usando o padrão /w3 isso já não acontece, porque o compilador vai reclamar das variáveis usadas que não foram declaradas.

Por isso aconselho: se puder usar, use o padrão /w3.
Se tem um sistema grande, vai ser um grande trabalho fazer o ajuste, podendo causar até erros aonde já funcionava.
Mas pode já adotar o padrão pra novas rotinas.

Aqu fiz o contrário do que indicaram:
Coloquei no fonte velho #pragma /w0
E fixei o compilador com /w3 /es2

Com isso, tudo que é novo já é feito desse modo. E os programas antigos, vou alterando um por vez.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Padrão /w3

Mensagem por fladimir »

Com relação a isto realmente é uma ótima prática

Agora na alteração me deparei com um problema... veja o final do código

Código: Selecionar todos

function Consulta()
    ...
	break(oErro)
return .F. 
o compilador da a mensagem: Warning W0028 Unreachable code

devido o break antes do return tipo não vai ler a linha debaixo... porém se eu tiro o return da outra mensagem...

Código: Selecionar todos

Warning W0007  Function 'CONSULTA' does not end with RETURN statement
E agora como resolver?
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Padrão /w3

Mensagem por Jairo Maia »

Acho que o problema está na forma de uso do Break.

Quando você usa o Break sem direcionamento, ele retorna para a linha imediatamente abaixo do End Sequence de onde ele ele foi chamado numa função ou bloco entre: Begin Sequence / End Sequence.

Quando você usa o Break com direcionamento, por exemplo: Break NomeDaFuncao(), ele retorna para a função que foi direcionado sem retorno para onde ele foi chamado, ou seja, a execução dá sequência de onde ele foi direcionado.

Não é possível receber o valor de Variável ou Objeto através de um Break, tal como um Return.

Acho que é isso.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Padrão /w3

Mensagem por JoséQuintas »

O erro "Warning W0028 Unreachable code" significa que NADA será executado depois de BREAK, e por isso aquela continuação do fonte não tem sentido.

Mas pera lá....
BREAK não é usado dentro de um BEGIN-END ? Algo como o EXIT do DO WHILE?

Código: Selecionar todos

BEGIN SEQUENCE WITH __BreakBlock()
    IF x = 10
       BREAK
   ENDIF
END SEQUENCE
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Padrão /w3

Mensagem por Jairo Maia »

Não. Break tem uma amplitude muito maior que isso. Exemplo:

Código: Selecionar todos

#include "inkey.ch"

Function Main()

 Alert( "Voce está na funcao Inicial" )

 BEGIN SEQUENCE
 
  Teste()

  Hb_Alert( "Voce nao pressionou ESC" ) // esta funcao não será executada se pressionar ESC...
 
 END SEQUENCE

 If LastKey() = K_ESC
  Hb_Alert( [Voce pressionou ESC, entao voce nao viu a mensagem;;"Voce nao pressionou ESC";;porque ela esta antes da linha END SEQUENCE.])
 EndIf

Return Nil

Function Teste()

 Hb_Alert( "Pressione ESC para entender o Break" )

 If LastKey() = K_ESC
  Break
 EndIf
 
Return Nil
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Padrão /w3

Mensagem por JoséQuintas »

Fiz um teste usando esse mesmo fonte.
Se colocar assim, dá o erro que foi mencionado.

Código: Selecionar todos

#include "inkey.ch"

Function Main()

 Alert( "Voce está na funcao Inicial" )

 BEGIN SEQUENCE

 Teste()

 Hb_Alert( "Voce nao pressionou ESC" ) // esta funcao não será executada se pressionar ESC...

 END SEQUENCE

 If LastKey() = K_ESC
 Hb_Alert( [Voce pressionou ESC, entao voce nao viu a mensagem;;"Voce nao pressionou ESC";;porque ela esta antes da linha END SEQUENCE.])
 EndIf

Return Nil

Function Teste()

 Hb_Alert( "Pressione ESC para entender o Break" )

 //If LastKey() = K_ESC
 Break
 //EndIf

Return Nil
Até tem sentido, porque se o BREAK é para exceções, faltaria a saída normal.
A saída, num caso destes, seria enganar o compilador:

Código: Selecionar todos

IF .T.
   BREAK
ENDIF
Aliás... se sempre sai com BREAK, tanto faz ter ou não, vai sair de qualquer jeito.
O uso é que está estranho mesmo, É como um IF sem ELSE, ou um ELSE sem IF.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Padrão /w3

Mensagem por JoséQuintas »

Um fonte assim ficaria confuso, por exemplo se alterar área de uso, e outras coisas.

Mas independente disso, se em consulta() sempre sai com break, ficou sem opção de escolha para com BREAK/sem BREAK.
Talvez melhor colocar a condição no fonte anterior.

Código: Selecionar todos

IF SeiLaPorQue
   Consulta()
   BREAK
ENDIF
Teria que analisar os fontes em conjunto.
Talvez usar o retorno de consulta()

Código: Selecionar todos

IF .NOT. Consulta()
   // o que fazer? BREAK?
ENDIF
Parece que o compilador fez bem em não aceitar o BREAK dessa forma.
Tem algo esquisito aí... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Padrão /w3

Mensagem por Kapiaba »

Eu uso assim, e vai tranquilo:

Código: Selecionar todos

/n /m /w /es1 /gc1
Abs.
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Padrão /w3

Mensagem por fladimir »

Vlw pessoal vou dar uma olhada
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Padrão /w3

Mensagem por JoséQuintas »

A vantagem do -w3 -es2 é mostrar aonde pode ter coisa errada.
Não se trata apenas de compilar ou não, ou de apenas tratar o erro, mas de confirmar se da forma que foi feito está correta.

Exemplo de um erro parecido:

Código: Selecionar todos

DO WHILE .NOT. Eof()
   ? "alguma coisa"
   EXIT
   SKIP
ENDDO
Aí também acusaria erro, porque o EXIT sai fora do DO WHILE, então SKIP em seguida é inútil.
Mas se SKIP é inútil, o DO WHILE também...
Então não se trata apenas de eliminar o erro do SKIP, mas de revisar o fonte, pra ver se era isso mesmo.
o BREAK indicado seria uma situação parecida com essa.
Se compilar com -w1 -es1, não acusa erro, mas o fonte continua esquisito.... rs

Se alterar para:

Código: Selecionar todos

IF .T.
   EXIT
ENDIF
Isso elimina o erro de compilação, mas de qualquer forma o fonte continua esquisito.

Essas são algumas checagens extras interessantes ao usar -w3 -es2.
É algo como ter um programador experiente te mostrando as coisas "esquisitas", que podem ser problema.
Às vezes é só resolver a mensgem de erro, mas às vezes é bom revisar o que acontece no fonte.

Isso num fonte pequeno tá bem visível, mas num fonte grande só mesmo com a ajuda do compilador.
(ou no caso do BREAK, que usa até fontes/rotinas diferentes).
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder