Add half-hearted support for Clang, because its `blocks' are deficient.
[finally] / FINALLY.3
CommitLineData
d58b8198
MW
1.\" -*-nroff-*-
2.TH control 3 "28 April 2023" "Straylight/Edgeware" "FINALLY macro package"
3.SH NAME
4FINALLY \- defer execution until scope exit
5.SH SYNOPSIS
6.nf
7.B "#include <finally.h>"
8
9.BI FINALLY( stmt );
10.BI FINALLY_TAGGED( tag ", " stmt );
11.fi
12.
13.SH DESCRIPTION
14.
15.SS "General usage of FINALLY"
16The
17.B FINALLY
18macro arranges that the statement
19.I stmt
20should be executed when control leaves the immediately enclosing scope,
21whether this is by just running off the end, or by explicit control
22flow, e.g.,
23.BR return ,
24.BR goto ,
25.BR break,
26or
27.BR continue .
28If a scope contains multiple
29.B FINALLY
30calls, then the statements are executed in reverse order.
31.PP
32In particular, if the macro call is placed at top-level within a
33function body, then
34.I stmt
35is executed when the function returns, either as a result of a
36.B return
37statement, or by running off the end of the function body.
38.PP
39With GNU-like compilers, you can arrange for the statement to be
40executed when control escapes the scope as the result of a C++ exception
41by setting the
42.B \-fexceptions
43compiler flag.
44.PP
45The statement will
46.I not
47be executed if control leaves the scope as a result of
48.BR longjmp (3)
49or similar. It also won't be executed if control `leaves' as a result
50of a call to
51.BR exit (3)
52or similar; but that's almost certainly what you want.
53.PP
54The
55.B FINALLY
56macro's expansion is syntactically one or more declarations. In C89
57code, therefore, it must appear at the head of a block, before any
58statements. In C99 or later, it may appear anywhere in a block.
59However, because it may expand to more than one declaration, it is not
60suitable for use in a
61.B for
62statement.
63.
64.SS "Macros and FINALLY_TAGGED"
65At most one use of
66.B FINALLY
67can occur on any given line of source code. In particular, this
68rule forbids macros which expand into more than one use of
69.BR FINALLY ,
70since the macro expansions will cause them all to be credited to the
71line holding the original expansion site. To avoid trouble, macro
72authors should use
73.B FINALLY_TAGGED
74instead. Each use of
75.B FINALLY_TAGGED
76on the same source line must have a distinct
77.I tag
78argument, which may be any identifier.
79.
80.SS "Nonlocal transfers, and thread and process exits"
81The statement will
82.I not
83be executed if control leaves the scope as a result of
84.BR longjmp (3)
85or similar. It also won't be executed if control `leaves' as a result
86of a call to
87.BR exit (3),
88.BR pthread_exit (3),
89.BR thrd_exit (3),
90or similar.
91.PP
92You didn't want
93.B FINALLY
94blocks to run at
95.BR exit (3)
96time. Almost all uses of
97.B FINALLY
98are to release process-local resources such as memory, file descriptors
99or locks, or something else similar. The kernel will release these by
100itself when the process exits, because leaking resources when processes
101crash would just be too awful to consider. All you'd achieve by
102carefully freeing memory prior to
103.BR exit (3)
104would be to waste time.
105.
106.SS "Setup and configuration"
107The
108.B FINALLY
109macro uses compiler-specific techniques. Not only does it need
110different implementations on different compilers, but it may require
111unusual compiler options and runtime support libraries to work.
112.PP
113Firstly, the
114.B <finally.h>
115header can work portably under C++11 or later, using RAII and lambdas:
116idiomatic C++ doesn't benefit much from this, but the facility is there
117anyway. If the header detects that such a compiler is in use (the macro
118.B __cplusplus
119is defined to a value greater than or equal to 201103), then it will use
120the C++-specific implementation.
121.PP
122Otherwise, the header checks the value of
123.BR FINALLY_CONFIG_FLAVOUR :
124it should be one of the following options.
125.TP
126.B NIL
127No support. An error is reported (using
128.BR #error ).
129.TP
130.B GCC_NESTED_FUNCTIONS
131Use the GNU C Compiler's support for nested functions and the
132.B cleanup
133function attribute. Note that this use of nested functions does not
134involve the use of trampolines, and does not require an executable
135stack. (This is verified as part of the package tests.)
31ac64c4
MW
136.TP
137.B CLANG_BLOCKS
138Use the LLVM Clang compiler's support for `blocks' and the
139.B cleanup
140function attribute. Depending on the environment, this may require the
141.B \-fblocks
142compiler option, and linking against the
143.B \-lBlocksRuntime
144library.
145.IP
146Support is only partial. When the statement is executed on exit from
147its scope, it sees the variable values that were current when the
148.B FINALLY
149declaration was processed, and not any changes since. As a result of
150this bug, the
151.B <finally.h>
152header will fail unless the macro
153.B FINALLY_TOLERATE_BUG_CAPTURE_COPIES
154is defined to a nonzero value, and will set
155.B FINALLY_BUG_CAPTURE_COPIES
156for your program to act on.
d58b8198
MW
157.PP
158If
159.B FINALLY_CONFIG_FLAVOUR
160is not set, then
161.B <finally.h>
162guesses one of these flavours based on the compiler version and other
163predefined macros. This guess may be wrong, and things may not work
164anyway because necessary compiler options or libraries aren't available.
165.PP
166The best way to set everything up correctly is to use the provided
167.B FINALLY_CHECK
168Autoconf macro. It will define
169.B FINALLY_CONFIG_FLAVOUR
170to a suitable value, and also report necessary compiler flags and
171libraries in the
172.B FINALLY_CFLAGS
173and
174.B FINALLY_LIBS
175makefile variables. See the
176.B finally.m4
177file's internal documentation for the details.
178.
179.SH BUGS
180The selection of supported compilers is extremely limited.
31ac64c4
MW
181.PP
182Clang doesn't work properly because its `blocks' capture a copy of the
183outer scope's variables, rather than closing over them properly.
d58b8198
MW
184.
185.SH AUTHOR
186Mark Wooding, <mdw@distorted.org.uk>