From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Joseph S. Myers" To: Joern Rennecke Cc: Ulrich Drepper , Geoff Keating , gcc@gcc.gnu.org, libc-alpha@sourceware.cygnus.com Subject: Re: Implementation of Date: Fri, 28 Jul 2000 19:04:00 -0000 Message-id: References: <200007282212.XAA00706@phal.cygnus.co.uk> X-SW-Source: 2000-07/msg00965.html 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