New `finally` keyword in GCC 15.1

Hi all,

I failed to document (or maybe it was added a bit later than when I finished the changelog for GCC 15) that there is a new GNAT extension available in GNAT/GCC 15, it is the finally keyword. You can read about it in the GNAT Reference Manual. There is not much documentation about it though nor examples. However, I came across this SPARK commit which provided some examples. I tested the first one with a quick gnatmake -gnatX0 XXX.adb and it compiled without much fuss.

Sooo… how could this be used? I am asking as a complete newbee, not as a critique :slight_smile: It is also nice to see that SPARK now supports it too!

Best regards,
Fer

1 Like

The first thought that comes to mind is something like files that you want to close if you successfully open them but later encounter an exception while parsing them. You can use the finally section to close the file regardless of whether the full process completed or exceptioned out.

3 Likes

It is a feature complement to object finalization. Finalization is an OO approach to the general problem of safe finalization. Finally is a procedural counterpart.

For example, let you have a mutex you seize to protect a critical code section. To ensure that the mutex gets released you can create a holder object that seizes the mutex on initialization and releases it on finalization. Then you place the holder in a scope like this:

declare
   Lock : Holder (Mutex’Access);
begin
   ... -- Critical section
end;

Now the procedural alternative would be:

Mutex.Seize;
begin
   ... -- Critical section
finally
   Mutex.Release;
end;

You can use it in smallish designs when procedural decomposition is sufficient.

Note also. You need to be very careful with the scope where you place finalize. In the example above it would be a bug to place Mutex.Seize after the begin. The compiler cannot protect you here.

4 Likes

As mentioned, this may come in handy in cases where any type of resources acquired during the main sequence_of_statements need to be freed when the block exits (i.e. semaphores, files, memory etc).

One interesting point, as mentioned above, might be that the finally block gets executed whether the main sequence_of_statements terminates normally or with an exception. The RM mentions that: after the main sequence_of_statements is executed, and after any potential exception_handler is executed but it’s not explicitly mentioned whether that’s the case for unhandled exceptions too where no handlers exist in the exception block? Assume that’s the case?

It also seems to be an abort-deferred region when applying ATC.

The RM

Note: This is not the Ada RM. AdaCore are leaving the the standard and beginning to develop an Ada derivation of their own.

mentions that: after the main sequence_of_statements is executed, and after any potential exception_handler is executed

Now, what happens if the finally part raises an exception?

1 Like

I guess same when the exception part raises. It will propagate out of the block. This is sort of inconsistent with the claimed purpose of finally should unhandled exception happen in the middle of. But what would you expect from Java-esque stuff? Alternatively one could nuke the program with Program_Error…