Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Gestión de errores (try/catch/finally) (https://www.clubdelphi.com/foros/showthread.php?t=91169)

Angel.Matilla 23-11-2016 12:19:04

Gestión de errores (try/catch/finally)
 
Estoy hecho un verdadero lío y sé que esto es básico, pero no me aclaro. Tengo este código:
try
Código:

{
    char cEntornoAnt[256] = "\0";
    TIniFile *fIni = new TIniFile(cEntornoAnt);

    GetPrivateProfileString("DATOS", "Entorno", "C:\\DatAfi21\\Gia.ini", cEntornoAnt, sizeof(cEntornoAnt), cInicio.c_str());

    if (!FileExists(cEntornoAnt))
          throw Exception("No se encuentra el fichero de configuracion antiguo.\nAvise al programador.");

    [Resto del código]
}
catch(Exception &exception)
{
    ShowMessage(exception.Message);
}
__finally
{
    delete cEntornoAnt;
    delete fIni;
}

Si lo pongo así al compilar me da un error E2188 Expression syntax en la declaración __finally.
Si anido otro try:
Código:

try
{
    char cEntornoAnt[256] = "\0";
    TIniFile *fIni = new TIniFile(cEntornoAnt);
    try
    {
          GetPrivateProfileString("DATOS", "Entorno", "C:\\DatAfi21\\Gia.ini", cEntornoAnt, sizeof(cEntornoAnt), cInicio.c_str());

          if (!FileExists(cEntornoAnt))
              throw Exception("No se encuentra el fichero de configuracion antiguo.\nAvise al programador.");

          [Resto del código]
    }
    catch(Exception &exception)
    {
          ShowMessage(exception.Message);
    }
}
__finally
{
    delete cEntornoAnt;
    delete fIni;
}

Entonces el compilador me da dos errores E2451 Undefined symbol 'identifier' en los dos deletes del final. ¿Qué estoy haciendo mal?

Snaked 23-11-2016 16:51:02

Hola Angel....

mira, prueba con esta estructura

Código:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Graphics::TBitmap* B = new Graphics::TBitmap;
  try
  {
    TPrinterSetupDialog *PS = new TPrinterSetupDialog(NULL);
    try
    {
      PS->Execute();
    }
    catch(...)
    {
      delete PS;
      throw;
    }
    delete PS;
    B->Width = Screen->Width;
    B->Height = Screen->Height;
  }
  catch(...)
  {
    delete B;
    throw;
  }
  delete B;
}


Snaked 23-11-2016 16:54:32

quizas sea que tienes que poner:

delete Form1->cEntornoAnt

o donde este situado el identificador

creo que el delete ese del Finally es redundante....pues los objetos locales de metodos y funciones se borran automaticamente por el compilador al salir de los mismos

Angel.Matilla 23-11-2016 17:37:15

Gracias por las respuestas. Ya encontré el error y es una tontería :o: Simplemente era sacar las declaraciones del try.
Código:

char cEntornoAnt[256] = "\0";
TIniFile *fIni;
   
try
{
    try
    {
          [...]
    }
    catch(...)
    {
    }
}


Snaked 24-11-2016 00:36:55

ah claro..... yo no cai en eso pero tampoco es que sea experto en try catch....creo que solo lo habre hecho 1 o 2 veces y la primera fue en el curso de programacion de C++ builder de auto-enseñanza que hice.... jejeejej

lo que si creo que me apetece es volver a repasarme el libro de programacion en C y ahondar un poco en otro de programacion C++ y ver si ahora, con un poco mas de experiencias a las espaldas lo cojo con soltura y vicio.

aguml 30-11-2016 16:51:59

__finally no es C++ estándar y solo funciona con los compiladores de Microsoft, por lo tanto en el c++builder no te va a funcionar. Además en tu código no lo necesitabas para nada y solo necesitabas quitarlo sin más.
Por otro lado ese código no está bien ya que si falla al obtener memoria, en tu código si o si intentará liberarla y eso es peligroso. Además cEntornoAnt es creado de forma estática e intentas liberar su memoria con delete, delete se usa para liberar la memoria obtenida con new. Así deberías ponerlo:
Código PHP:

char cEntornoAnt[256] = '\0';
try
{
     
TIniFile *fIni = new TIniFile(cEntornoAnt);
     try
     {
          
GetPrivateProfileString("DATOS""Entorno""C:\\DatAfi21\\Gia.ini"cEntornoAntsizeof(cEntornoAnt), cInicio.c_str());

          if (!
FileExists(cEntornoAnt))
               throw 
Exception("No se encuentra el fichero de configuracion antiguo.\nAvise al programador.");

          [
Resto del código]
     }
     catch(
Exception &exception)
     {
          
ShowMessage(exception.Message);
     }
     
delete fIni;



mamcx 30-11-2016 16:59:06

Ten en cuenta que C++ usa RAII:

https://es.wikipedia.org/wiki/RAII
Cita:

La técnica RAII es vital al escribir código C++ seguro frente a excepciones
Supongo que C++ builder lo permite...

j0seant 30-11-2016 17:24:07

Cita:

Empezado por aguml (Mensaje 511372)
__finally no es C++ estándar y solo funciona con los compiladores de Microsoft, por lo tanto en el c++builder no te va a funcionar.

__finally existe en C++Builder desde la versión 3 o 4, y funciona (aunque sea una extensión de Microsoft). No entro en si es más o menos recomendable usarlo, evidentemente siempre que se pueda usar RAII mucho mejor.

Muy útil también para estos casos "unique_ptr" o "auto_ptr".

exmachina 30-11-2016 23:18:37

Cita:

Empezado por j0seant (Mensaje 511375)
__finally existe en C++Builder desde la versión 3 o 4, y funciona (aunque sea una extensión de Microsoft). No entro en si es más o menos recomendable usarlo, evidentemente siempre que se pueda usar RAII mucho mejor.

Muy útil también para estos casos "unique_ptr" o "auto_ptr".

Que yo sepa el uso de los bloques try...catch..finally tienen un coste, tanto en memoria como en eficiencia, sobre todo cuando no se intercepta unas excepciones concretas-> es decir cuando se interceptan todas las excepciones y se debe desenrollar toda la pila. En internet pueden encontrarse multitud de documentos que explican esto (basicamente quiere decir que es muy comodo usar las excepciones pero repercuten en el rendimiento)

Sobre __try, __except y __finally (SEH) y cosas similares (controlar errores y excepciones en C++) en Windows :
https://msdn.microsoft.com/en-us/library/hh279678.aspx
https://msdn.microsoft.com/en-us/library/swezty51.aspx

Y por cierto, aunque no no soy programador ya se que existen documentos similares a este, pero hacen referencia a C++/CLI y aun asi sigue existiendo el mismo problema, aunque no se mencione.

Un saludo


La franja horaria es GMT +2. Ahora son las 09:48:52.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi