Brak return value za blokiem __finally == "W8070 Function should return a value"

0

Mam taką metodę:

int TForm1::x()
{
  try
  {
    return 1;
  }
  __finally
  {
    y(); // y() się wykona
    // return 2; // ok, z tym jest: E2551 Return statement not allowed in __finally block
  }
  z(); // z() się oczywiście nie wykona
  return 3; // return też się nie wykona, ale bez tego jest: W8070 Function should return a value
}

O co tu chodzi? Dlaczego kompilator krzyczy, że "Function should return a value"? Przecież try kończy się returnem i zaraz po __finally metoda zwraca. Bez tego "return 3", który i tak się nie wykona mam warninga.

1

Pewnie słaba heurystyka kompilatora sprzed 20 lat. Myślę, że zasadniejsze są następujące pytania:

  1. czemu używasz jakiegoś __finally zamiast catch?
  2. czemu używasz buildera w 2008+?
0
kq napisał(a):

Pewnie słaba heurystyka kompilatora sprzed 20 lat. Myślę, że zasadniejsze są następujące pytania:

To jest akurat Builder XE8 sprzed 3 lat

  1. czemu używasz jakiegoś __finally zamiast catch?

No bo catch łapie wyjątki, a __finally wykona się niezależnie od tego, czy wyjątek wystąpi czy nie. Przykład, który podałem jest maksymalnie uproszczony, ale w niektórych sytuacjach __finally może być przydatne...

  1. czemu używasz buildera w 2008+?

wiem, wiem... no niestety wdepnąłem w stary projekt i nie mam wyjścia

EDIT: Poza tym, jeśli tylko zmienię __finally na catch, to jeśli chodzi o warninga jest to samo.

0

To jest akurat Builder XE8 sprzed 3 lat
Po tagach założyłem C++Buildera, sorry.

__finally - rozumiem co to ma robić, ale wyżej wymieniony kod jest niepoprawny w C++ ;​) Tak czy inaczej, możesz po prostu użyć boostowego SCOPE_EXIT czy własnego podobnego rozwiązania. Choć w tym przykładzie bym zrobił po prostu:

int TForm1::x()
{
  try
  {
    return 1;
  }
  catch(...){}  
  //__finally
  y();
  return 2;
}
0

W "builderowym c++" widocznie kod jest poprawny ;).
Nieźle się zdziwiłem, jak odkryłem, że po returnie w try funkcje nie zwracają natychmiast tylko coś tam jeszcze się dzieje (__finally).
Czyli nie ma innego sposobu na pozbycie się tego warninga? Taki pseudo return może trochę zmylić.

0

Może jest, musiałby się jakiś spec od buildera wypowiedzieć. Zobacz czy możesz użyć jakiegoś __builtin_unreachable() czy coś.

0
git napisał(a):

Nieźle się zdziwiłem, jak odkryłem, że po returnie w try funkcje nie zwracają natychmiast tylko coś tam jeszcze się dzieje (__finally).

Ale czego się spodziewasz skoro blok __finally ma wykonać się zawsze? Wiesz jaki był zamysł wprowadzenia tego bloku? Załóżmy, że powołujesz dynamicznie komponent (dowolny nawet jakieś TQery do bazy) wtedy w __finally umieszczamy zwolnienie zasobów które się wykona nawet w przypadku wystąpienia niewyłapanego wątku. Tak wiem, że takie zwalnianie zasobów w XXI wieku nie robi się ręcznie ;)

git napisał(a):

Czyli nie ma innego sposobu na pozbycie się tego warninga? Taki pseudo return może trochę zmylić.

Masz dwie możliwości. Albo użyć odpowniedniej #pragma warn http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Pragma_warn albo przepisać nieco kod w tym stylu:

int TForm1::x()
{
  int RetVal = 0;

  try
  {
    RetVal = 1;
  }
  __finally
  {
    y();
  }
  return RetVal;
}

Osobiście wolę takie rozwiązanie i stosuję zazwyczaj, szczególnie jak mam kilka returnów z funkcji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1