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] |
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] |