revision of N4226
Jens Maurer

N4357: [[noexit]] attribute for main


This paper proposes to add a [[noexit]] attribute, only applicable to the function main, as a hint to eliminate destructor calls for objects with static storage duration. More detailed rationale and discussion is available in the predecessor paper N4226.

This paper was discussed during the November 2014 WG21 meeting in Urbana-Champaign. It was initially approved by the Evolution Working Group, but rejected by the Core Working Group. The latter opined that in order to benefit from the proposal, undesirable linker magic would be required. A way of specifying global options, attributes, or #pragmas visible in every translation unit would be preferred. After that, Evolution Working Group discussed this proposal again, noting that it supported the general idea, but required a more comprehensive paper analyzing the effects on different translation units, the effects on shared libraries, and the effects (such as undefined behavior) if violated. Also, measurements on the resource savings (such as ROM and RAM size) would be much appreciated.

This paper does not attempt to address the WG21 concerns raised in the discussion, it merely documents the state of the discussion to facilitate future work.


Add a new paragraph after 3.6.1 basic.start.main paragraph 5:
[ Note: The function main may be defined with the noexit attribute; see 7.6.6 dcl.attr.noexit. -- end note ]
Add a new section 7.6.6 dcl.attr.noexit:
7.6.6 [dcl.attr.noexit] Noexit attribute

The attribute-token noexit specifies that a program never exits in a normal fashion. It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present. The attribute may be applied to the declarator-id of the definition of the function main (3.6.1 basic.start.main).

If the function main is defined with the noexit attribute, leaving the function main (3.6.1 basic.start.main) results in undefined behavior and an odr-use (3.2 basic.def.odr) of the function std::exit in any translation unit is ill-formed; no diagnostic required. [ Note: The function main may exit via an exception, in which case std::terminate is called (15.5.1 except.terminate). Destructors for objects with static storage duration are never invoked if main is defined with the noexit attribute (3.6.3 basic.start.term). -- end note ]

Change in 18.5 paragraph 6:
Implementation limits: The implementation shall support the registration of at least 32 functions. [ Note: If the function main is defined with the noexit attribute (7.6.6 dcl.attr.noexit), calling the atexit function has no effect, since the functions so registered are never invoked. -- end note ]