This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: math.h float_t and double_t not typedef'ed when FLT_EVAL_METHOD defined


I have checked in a modified version of the patch.

For implementation-defined FLT_EVAL_METHOD values, it will be assumed that float_t and double_t have been defined for the configuration (e.g. config.h or ieeefp.h).

I have removed the _FLOAT_T_DEFINED and _DOUBLE_T_DEFINED flags and the check in the log2f macro. I have also defaulted float_t to float and double_t to double if FLT_EVAL_METHOD is not defined as was done prior to the patch.

In the future, I intend to remove the log2f macro and replace the log2f function with the BSD version which is consistent with the other log functions.

-- Jeff J.

On 12/17/2012 01:05 PM, Craig Howland wrote:
Jeff or Corinna:
Ping?  (Oddly enough, while I got my copy from the list server, I don't
see this message in the mail archive.)
Craig


On 12/11/2012 05:57 PM, Craig Howland wrote:
Here, finally, is a patch. I have changed the approach from what I first
proposed to the alternative of not defining float_t and double_t when
FLT_EVAL_METHOD is not recognized. The reasons are explained in the
comments in
the patch.
The end result for the state of defining float_t and double_t will not be
different for Jordy's test case, but the test case will pass because
defining
log2f() as a macro is now skipped for the case.
Craig

2012-12-11 Craig Howland <howland@LGSInnovations.com>

* libc/include/math.h: Add recognition of values 1 and 2 for
FLT_EVAL_METHOD; do not define log2f() macro if float_t is not defined.


On 11/16/2012 08:01 PM, Craig Howland wrote:
Yes, the manner in which math.h handles float_t and double_t is
lacking, and
yes, the solution is quite similar to what you list. The problem is
that the
else case is tricky, when the value is not 0, 1, or 2.

...

The two approaches for unknown values are to default to something or
to define
nothing. In the code below, you can see that I opted for the former,
along with
the reason for so doing.

...

Thoughts and comments on how to handle the if? Even though I made the
tentative
choice of a default when I wrote this in 2010, my present inclination
is that
nothing should be defined so that such an implementation would have
to put them
in somehow for things which use them to work. (It would be less of a
mess if the
standard had put float_t and double_t in float.h along with
FLT_EVAL_METHOD.)

Craig


On 11/16/2012 06:34 AM, Jordy Potman wrote:
Hi,

I am using Newlib with a clang based compiler for our architecture.

I think I have found an issue in Newlib's math.h.

Newlib's math.h does not typedef float_t and double_t when
FLT_EVAL_METHOD is defined.

math.h lines 143-147:
143: #ifndef FLT_EVAL_METHOD
144: #define FLT_EVAL_METHOD 0
145: typedef float float_t;
146: typedef double double_t;
147: #endif /* FLT_EVAL_METHOD */

Clang's float.h defines FLT_EVAL_METHOD (I think gcc's float.h does as
well), which I think is correct according to section 5.2.4.2.2
paragraph
8 of the C99 standard.

Newlib's math.h defines the log2f function as a macro which uses
float_t.

math.h lines 354-357:
354: extern float log2f _PARAMS((float));
355: #if !defined(__cplusplus)
356: #define log2f(x) (logf (x) / (float_t) _M_LN2)
357: #endif

This causes a compilation error if a program includes float.h before
math.h and uses the log2f function:
$ cat log2f_test.c
#include<float.h>
#include<math.h>

float f(float a) {
return log2f(a);
}
$ xentium-clang -std=c99 -c log2f_test.c
log2f_test.c:5:10: error: use of undeclared identifier 'float_t'; did
you mean 'float'?
return log2f(a);
^
/home/potman/opt/xentium-tools-1.0.beta9-linux64/bin/../sysroots/default/include/math.h:359:31:


note: expanded from macro 'log2f' #define log2f(x) (logf (x) / (float_t) _M_LN2) ^ 1 error generated.

I have changed math.h lines 354-357 to the following in our
implementation:

#ifndef FLT_EVAL_METHOD
#define FLT_EVAL_METHOD 0
#endif /* FLT_EVAL_METHOD */
#if FLT_EVAL_METHOD == 1
typedef double float_t;
typedef double double_t;
#elif FLT_EVAL_METHOD == 2
typedef long double float_t;
typedef long double double_t;
#else
typedef float float_t;
typedef double double_t;
#endif

This is my interpretation of how float_t and double_t should be
typedef'ed depending on the value of FLT_EVAL_METHOD as is described in
section 7.12 paragraph 2 of the C99 standard. However I am not a C99
standard expert.

Jordy


Index: libc/include/math.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/math.h,v
retrieving revision 1.48
diff -u -p -r1.48 math.h
--- libc/include/math.h	16 Oct 2012 18:45:23 -0000	1.48
+++ libc/include/math.h	18 Dec 2012 21:20:35 -0000
@@ -140,11 +140,37 @@ extern double fmod _PARAMS((double, doub
 
 /* ISO C99 types and macros. */
 
-#ifndef FLT_EVAL_METHOD
-#define FLT_EVAL_METHOD 0
-typedef float float_t;
-typedef double double_t;
+/* FIXME:  FLT_EVAL_METHOD should somehow be gotten from float.h (which is hard,
+ * considering that the standard says the includes it defines should not
+ * include other includes that it defines) and that value used.  (This can be
+ * solved, but autoconf has a bug which makes the solution more difficult, so
+ * it has been skipped for now.)  */
+#if !defined(FLT_EVAL_METHOD) && defined(__FLT_EVAL_METHOD__)
+  #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+  #define __TMP_FLT_EVAL_METHOD
 #endif /* FLT_EVAL_METHOD */
+#if defined FLT_EVAL_METHOD
+  #if FLT_EVAL_METHOD == 0
+    typedef float  float_t;
+    typedef double double_t;
+   #elif FLT_EVAL_METHOD == 1
+    typedef double float_t;
+    typedef double double_t;
+   #elif FLT_EVAL_METHOD == 2
+    typedef long double float_t;
+    typedef long double double_t;
+   #else
+    /* Implementation-defined.  Assume float_t and double_t have been
+     * defined previously for this configuration (e.g. config.h). */
+  #endif
+#else
+    /* Assume basic definitions.  */
+    typedef float  float_t;
+    typedef double double_t;
+#endif
+#if defined(__TMP_FLT_EVAL_METHOD)
+  #undef FLT_EVAL_METHOD
+#endif
 
 #define FP_NAN         0
 #define FP_INFINITE    1

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