This document relates to issues described in reflector messages 13016 (June 2013) and 13157 (February 2014).
Various optional features, in C11 and TR and TS documents, are controlled by feature test macros __STDC_WANT_*. However, different such macros follow different rules. It would be desirable to have greater consistency between these macros. Similar issues apply to reservations with external linkage of identifiers from such optional features. This document describes the differences in these regards between optional features. Rather than proposing concrete wording changes, it should be seen as a request for direction from WG14 regarding what the preferred semantics in this area are, with a view to suitable wording being written later that can be used consistently by any such features included in C2x, and any TR or TS documents revised in future.
__STDC_WANT_LIB_EXT1__ (Annex K) follows the following practice: being defined to 0 means the features are not declared or defined; being defined to 1 means the features are declared or defined; being undefined leaves it implementation-defined whether the features are declared or defined; other values for the macro do not have specified semantics; any differences in definitions of the macro for inclusions of affected headers must be diagnosed.
The requirement “shall be defined identically for all inclusions of any headers from subclause K.3” appears to require a diagnostic if the definition changes between multiple inclusions of the same header, contrary to normal multiple-include optimization where a second include of the same header could generally be ignored – and “identically” would suggest identical token sequences (meaning a diagnostic if the expansion is 1 for one include and 1L for another include; this probably requires implementation extensions to implement such a diagnostic, when no other standard feature would require that particular extension).
__STDC_WANT_LIB_EXT2__ (TR 24731-2) has similar requirements to __STDC_WANT_LIB_EXT1__, except that the macro being undefined is equivalent to it being defined as 0 rather than it being implementation-defined whether the symbols are visible in that case. __STDC_WANT_MATH_SPEC_FUNCS__ (ISO 24747) also follows this practice.
The macros from the parts of TS 18661 follow a simpler practice. Given the resolution to TS 18661 DR#3, all that is relevant is whether the feature test macro is defined or undefined when a relevant header is first included. There is no difference between the macro values 0, 1 or anything else. DR#3 adds the requirement for the same set of such macros to be defined for the first inclusion of all such headers. The macros in question are __STDC_WANT_IEC_60559_BFP_EXT__, __STDC_WANT_IEC_60559_DFP_EXT__, __STDC_WANT_IEC_60559_TYPES_EXT__, __STDC_WANT_IEC_60559_FUNCS_EXT, __STDC_WANT_IEC_60559_ATTRIBS_EXT__. Note that different macros may affect different headers; the requirement is for the same set to be defined before including any header affected by any of those macros.
The simplest semantics for feature test macros, which I suggest be adopted for all such macros, might be similar to those for TS 18661: all that matters is whether the macro is defined or undefined, and the set of feature test macros defined must be the same for all inclusions of any standard library headers (or at least for all inclusions of any headers from the set affected by a particular macro), but no diagnostic is required for violations of that rule (given the problems with how a diagnostic requirement interferes with multiple-include optimization).
The issue with reservations with external linkage is similar. K.3.1.2 says “All identifiers with external linkage in any of the following subclauses are reserved for use as identifiers with external linkage if any of them are used by the program. None of them are reserved if none of them are used.”. Does this mean:
(a) a reservation with external linkage if any of those identifiers is used with external linkage by the program (even if the program does not include any standard header and is using the identifier for some unrelated purpose); or
(b) a reservation with external linkage if any of those identifiers is used with external linkage by the program, having included the relevant header with __STDC_WANT_LIB_EXT1__ appropriately defined for the header to declare the identifier; or
(c) something else?
If (a), “if any of them are used by the program. None of them are reserved if none of them are used” seems a bit pointless – an identifier not being reserved is only useful if you can use it. If (b), what happens if a user of an implementation that defines __STDC_LIB_EXT1__ declares printf_s themselves (as per 7.1.4#2 – I presume that all of 7.1.4 applies to the functions in Annex K as it does to those in clause 7) and then uses it, intending to get the standard library function – is that permitted, and does that cause the other functions to be reserved? I suspect the desired answer is more like:
(c) a reservation with external linkage if any of those identifiers is used with external linkage and the program does not provide an external definition for that identifier. That is, a program may define its own functions using any of the Annex K names, as long as it (i) doesn't include any standard header with conflicting declarations of them and (ii) doesn't try to use anything from Annex K at the same time as defining its own function with one of those names. But K.3.1.2#2 doesn't exactly make this clear.
TR 24731-2 has the same issue, while other documents defining optional features with external linkage (including TR 18037, which does not have any feature test macros since it puts its new functions in separate headers) do not seem to address the issue at all. For TS 18661, there would also be the issue of whether, for example, using an identifier from parts 3 or 4 thereby causes reservation of identifiers from parts 1 or 2 even if the feature test macros for those parts are not defined.