The new standard C (ISO/IEC 9899:2023, aka C23),
in the Annex H, several macros and types are defined,
relative to real and complex arithmetic,
subject to the standard ISO/IEC 60559
(floating-point arithmetic).
According to subsection H.1, there are three
implementation-defined macros to test conformance
with the definitions of Annex H.
__STDC_IEC_60559_TYPES__
__STDC_IEC_60559_BFP__
__STDC_IEC_60559_DFP__
In addition, to "activate" the associated macros and types,
the user has to define the macro:
__STDC_WANT_IEC_60559_TYPES_EXT__
The wording of the standard is clear in several details:
- If
__STDC_IEC_60559_BFP__is defined by the compiler, it implies that_FloatN,_FloatN_tand other_FloatN*types are defined. - If
__STDC_IEC_60559_DFP__is defined by the compiler, it implies that_DecimalN,_DecimalN_tand other_DecimalN*types are defined. - In either case, the macro
__STDC_IEC_60559_TYPES__is defined. - If the macro
__STDC_IEC_60559_TYPES__is defined, it means that at least one of the macros__STDC_IEC_60559_BFP__or__STDC_IEC_60559_DFP__(or both) is defined.
In subsection H.11, the type long_double_t is added to <math.h>.
However, I cannot deduce under which conditions one can ensure the existence of long_double_t in a given implementation.
QUESTION:
If __STDC_IEC_60559_TYPES__ is defined,
is it enough to be sure that long_double_t is also defined in <math.h>?
My doubt comes from the following particular case that could arise:
__STDC_IEC_60559_TYPES__and__STDC_IEC_60559_DFP__are defined, but__STDC_IEC_60559_BFP__is not defined.
In this case, decimal types are defined.
However, long_double_t is not a decimal type.
SUB-QUESTION:
Is the macro __STDC_IEC_60559_BFP__ required to exist in order to ensure existence of long_double_t?
COMMENTS:
As @John Bollinger explains in his answer,
the existence of *BFP__ and/or *DFP__ macros
only ensures that _FloatN and _DecimalN exist
for certain small values of N.
(I was aware of that detail, but my explanation was not the best.)
TL;DR: the minimum basis for relying on a conforming implementation to provide
long_double_tis that it defines macro__STDC_IEC_60559_TYPES__to202311L.However, the translation unit must also define
__STDC_WANT_IEC_60559_TYPES_EXT__(to anything) before including math.h for the first time for that definition to actually be exposed. (C23 H.8/1)Apparently not so clear.
As a preliminary matter, the spec says
This must be understood to relieve implementations from conforming to anything in the annex if they do not define
__STDC_IEC_60559_TYPES__to that specific value (even if they define it to some other value). This is an intentional forward-compatibility measure.The spec goes on to say:
Note well that per the previous, neither that provision nor anything else in the annex applies unless
__STDC_IEC_60559_TYPES__is defined to exactly202311L. Otherwise, all bets are off as far as Annex H (of C23) is concerned. For example, an implementation that defined__STDC_IEC_60559_TYPES__to nothing, and did not define either__STDC_IEC_60559_BFP__or__STDC_IEC_60559_DFP__, would not for that reason fail to conform.Not exactly. The spec does not associate any requirements with an implementation defining
__STDC_IEC_60559_BFP__alone. In addition to the general gating by definition of__STDC_IEC_60559_TYPES__, discussed above, the spec explicitly conditions some of the particular provisions in this area on the latter macro being defined.When all those conditions are met, a conforming implementation provides types
_Float32and_Float64, and those are equivalent tofloatanddouble, respectively. Also, under those circumstances, iflong doublecorresponds to one of the ISO 60559 binary exchange formats for some width N greater than 64, then the implementation provides the corresponding_FloatNtype as an equivalent tolong double. Other_FloatNtypes are allowed, but not required, and the set of them is implementation-defined. (H.2.1/4)A conforming implementation that binds itself to the provisions of this annex provides
_FloatN_tin its math.h for each_FloatNtype it provides.Again, implementations are not bound to anything in the annex unless they define
__STDC_IEC_60559_TYPES__appropriately. In that case,__STDC_IEC_60559_DFP__being defined implies that_Decimal32,_Decimal64, and_Decimal128are provided. Additional_DecimalNtypes are explicitly allowed, and that the set of such additional types is implementation defined.When the provisions of the annex apply at all, math.h will provide a
_DecimalN_tcorresponding to each_DecimalNthat the implementation defines.No, there is no such requirement. The logic is the other way around. As already discussed, none of Annex H applies unless
__STDC_IEC_60559_TYPES__is defined appropriately. If it is, then at least one of the other two macros must also be defined, but one of those being defined is not a basis for concluding anything about__STDC_IEC_60559_TYPES__.More specifically, this applies only if
__STDC_IEC_60559_TYPES__is defined to exactly202311L.Macro
__STDC_IEC_60559_TYPES__being defined to exactly202311Lis enough to be sure thatlong_double_tis available from the implementation. The annex does not place any additional conditions on that. The program does need to opt in, however. C23 H.8/1:You wrote:
True.
Who says? C23 6.2.6.1/1:
That subclause does not define the representation of any FP types.
There is no requirement that either
long doubleorlong_double_tbe a binary type. There seems not even to be a requirement that those two types be equivalent, though I would expect that as a quality of implementation matter.But there is no problem even if
long_double_tis a binary type.__STDC_IEC_60559_BFP__not being defined does not imply that the implementation does not provide any binary FP types. It means only that the implementation declines to promise that it conforms to all the provisions of Annex H with regard to binary FP types.No. H.11/6 specifies that
long_double_tis available from math.h, subject to program opt-in as discussed above, and that is not otherwise conditioned on anything other than the same__STDC_IEC_60559_TYPES__feature test macro on which everything in the annex is conditioned. Thereore, if a conforming implementation defines__STDC_IEC_60559_TYPES__to202311Lthen its math.h defineslong_double_tto those programs that opt in.