2024-12-21
integration into IS ISO/IEC 9899:202y
document number | date | comment |
---|---|---|
n3424 | 202412 | Original proposal |
CC BY, see https://creativecommons.org/licenses/by/4.0
The current wording in 6.7.13.8.1 has lead to misunderstandings about
the status of function calls with respect to the [[reproducible]]
and [[unsequenced]]
attributes for the case that such an attributed function does not
return. It seems that the corresponding gcc attributes __attribute__((pure))
and __attribute__((const))
assumed that such calls always return, without clearly documenting that
expectation, nor by documenting its reach.
Clearly, such an expectation makes sense, since otherwise a side effect could be inhibited by a call that does not return. Thus several optimizations that are the goal of these attributes would not be valid.
Currently this misunderstanding has the effect that gcc distinguishes the C attributes and their gnu predecessors even for the cases where function prototypes otherwise agree. The goal of this paper is to revert this unfortunate incident and establish the C attributes as a superposition of the gnu attributes.
The most important cases for non returning functions are already
covered by the current wording. In particular, calling functions that
implicitly change program state by closing streams (exit
and quick_exit
), by changing callback state
(exit
, quick_exit
and thread_exit
) are already prohibited. The aim
of this paper is to clarify this situation and to apply this rule more
widely, namely to prohibit termination of the execution whenever a side
effect may reasonably be expected during program termination.
Nevertheless, several cases of non-returning functions are not yet covered:
longjmp
.abort
, _Exit
).assert
invocation triggers.All these cases concern situations that are usually not taken into
account by optimizers. In particular, the resulting status of the
execution is specifically determined by wording for these features. Thus
not allowing the use of these features could change the behavior of a
function call from defined (whatever is defined for abort
, for example) to undefined. We don’t
think that the introduction of undefined behavior in that way is
reasonable.
New text is underlined green, removed text is
stroke-out red.
Add at the end of 6.7.13.8.1, p4, that talks about the effects that are considered for the attributes:
Similarly, a function call expression E that does not return to its caller is considered to have a visible effect on the execution state; this not withstandingare not considered for the effects they produce.
- an invocation of
longjmp
that bypasses E,- an invocation of
abort
or_Exit
,FNT1)- an invocation of
assert
,FNT2) and- the generation of a signal, interrupt or trap that terminates the execution,
FNT1) Note that in particular the functionsexit
,quick_exit
andthrd_exit
have visible side effects because they close streams and modify the states ofatexit
handlers,at_quick_exit
handlers andtss_t
destructors, respectively.
FNT2) Here, in case the asserted expression evaluates to
false, even the diagnostic output that the assert
macro produces is not considered as
an effect.
Modify p7:
A store operation to an object X that is sequenced during a function call such that both synchronize is said to be observable if X is not local to the call, if the lifetime of X ends after the call, if the stored value is different from the value observed by the call, if any, and if it is the last value written before the termination of the call. An evaluation of a function callFNT0) is effectless if any
storeoperation with side effect that is sequenced during the call is the modification of an object X that synchronizes with the call; if additionally the operation is observable, there shall be a unique pointer parameter P of the function such that any access to X shall be to an lvalue that is based on P. A function pointer value f is effectless if any evaluation of a function call that calls f is effectless. A function definition is effectless if the derived function pointer value is effectless.
Add <assert.h>
,
<setjmp.h>
and <stdlib.h>
to the Forward references.
Thanks to Jan Hubicka and Joseph Myers for discussion and feedback.