[Cfp-interest] constant rounding modes and type-generic macros

Jim Thomas jaswthomas at sbcglobal.net
Sat Apr 7 17:26:33 PDT 2012


This is intended as a summary of discussion the past few weeks about how constant rounding modes affect functions invoked by type-generic macros in <tgmath.h>. We'll discuss and try to wrap up this issue at our April meeting. 

The current CFP spec (11) has:

----------
Within the scope of an FENV_ROUND directive establishing a mode other than FE_DYNAMIC, all floating-point operators and invocations of functions indicated in Table 2 below, for which macro replacement has not been suppressed (7.1.4), shall be evaluated according to the specified constant rounding mode (as though no constant mode was specified and the corresponding dynamic rounding mode had been established by a call to fesetround). Invocations of functions for which macro replacement has been suppressed and invocations of functions other than those indicated in Table 2 shall not be affected by constant rounding modes — they are affected by (and affect) only the dynamic mode. Floating constants (6.4.4.2) that occur in the scope of a constant rounding mode shall be interpreted according to that mode.
----------

and (16) adds the following to 7.25:

----------
A type-generic macro corresponding to a function indicated in Table 2 is affected by constant rounding modes (7.6.2).
----------

This implies that functions invoked by <tgmath.h> macros are affected unless macro replacement has been suppressed. Thus in

#define STDC_WANT_IEC_60559_BFP
#include <tgmath.h>
#include <fenv.h>
double d;
float f;
…
{
	#pragma STDC FENV_ROUND FE_UPWARD
	…
	// Case 1
	… cbrt(d) …
	…
	// Case 2
	… cbrt(f) …
	…
	// Case 3
	#undef cbrtf
	… cbrt(f) …
	…
	// Case 4
	#undef cbrt
	… cbrt(d) …
	…
	// Case 5
	… cbft(f) …
	…
}

the current CFP spec says:

Case 1 - which invokes function cbrt shall be affected by pragma, because user has not suppressed macro expansion for cbrt. Note that <tgmath.h> may itself undef cbrt, so must take care to assure the call is affected

Case 2 - which invokes function cbrtf shall be affected by pragma, because user has not suppressed macro expansion for cbftf

Case 3 - which invokes function cbrtf shall not be affected by pragma, because user has suppressed macro expansion for cbrtf

Case 4 - which invokes cbrt (without help from suppressed <tgmath.h> macro) shall not be affected by pragma, because user suppressed macro expansion for cbrt

Case 5 - same as Case 4 but with argument converted to double

How does this requirement fit with C11? C11 leaves it unspecified whether functions invoked by <tgmath.h> macros are subject to macro replacement. The example in C11 6.5.1.1 provides a sample implementation for the <tgmath.h> cbrt macro using the _Generic macro. This implementation disables macro expansion for all the functions it invokes. Thus it does not give the CFP-specified behavior above in Cases 1 and 2. However, C11 does not say or imply that this sample implementation is definitive. 

The following modification of the sample implementation in 6.5.1.1 would give the CFP-specified behavior:

      #define cbrt(X) _Generic((X),                   \
                                  long double: cbrtl(X),     \
                                  default: __round_wise_cbrt(X),          \
                                  float: cbrtf(X)
                                 
where __round_wise_cbrt is affected by the constant rounding mode pragma (like cbrt where <math.h> but not <tgmath.h> has been included).

Any concerns about what we've specified? Is the behavior good for users? Is it reasonable to implement? Does it fit well enough with C11?

-Jim


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20120407/7ac0dde0/attachment-0001.html 


More information about the Cfp-interest mailing list