This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Implementation of <tgmath.h>


On Fri, 28 Jul 2000, Joern Rennecke wrote:

> Another approach would be to cast 0.25 to the argument type, and test if
> that's non-zero.  If so, we are dealing with a floating point type.

This pointed the way to the following implementation.  It won't solve the
technical issue of the wrong functions being called sometimes if double
and long double are the same size, but as long as in such cases they have
the same representation and the return type from the statement expression
is correct the `as if' rule may mean this does not affect conformance.  I
have ignored questions of complex types; the method can probably be
extended.  While it works, it somewhat exceeds the usual standards of
obscurity of glibc macros, and new builtin functions would yield much
clearer results while avoiding problems from the use of typeof and
statement expression extensions.  Test code is included below the macros
so you can compile with -DTEST_EXPR=whatever and see diagnostics telling
you which two of the three floating types are not the tgmath type for the
expression given.

/* 1 if 'type' is a floating type, 0 if 'type' is an integer type.
   Allows for _Bool.  Expands to an integer constant expression.
*/
#define __floating_type(type) (((type)0.25) && ((type)0.25 - 1))

/* The tgmath real type for T, where E is 0 if T is an integer type and
   1 for a floating type.
*/
#define __tgmath_real_type_sub(T, E) __typeof__(*(0 \
		     ? (__typeof__(0 ? (double *)0 : (void *)(E)))0 \
		     : (__typeof__(0 ? (T *)0 : (void *)(!(E))))0 \
		     ))

/* The tgmath real type of EXPR.  */
#define __tgmath_real_type(expr) __tgmath_real_type_sub(__typeof__(expr), \
					__floating_type(__typeof__(expr)))

/* Test compatibility by compiling and seeing which of these assignments
   are with incompatible types.  Define TEST_EXPR to the expression
   to test.
*/

#ifndef TEST_EXPR
#define TEST_EXPR 1
#endif

__tgmath_real_type(TEST_EXPR) *t;
float *f;
double *d;
long double *ld;

void
foo (void)
{
#line 1 "not float"
  f = t;
#line 1 "not double"
  d = t;
#line 1 "not long double"
  ld = t;
}

-- 
Joseph S. Myers
jsm28@cam.ac.uk


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]