This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
struct ldieee should be packed
- From: Shoichi Sakon <s-sakon at ap dot jp dot nec dot com>
- To: "newlib at sourceware dot org" <newlib at sourceware dot org>
- Date: Sat, 30 Jan 2016 06:56:13 +0000
- Subject: struct ldieee should be packed
- Authentication-results: sourceware.org; auth=none
- Deferred-delivery: Sat, 30 Jan 2016 06:56:00 +0000
Hello,
The following test program prints 1.0 instead of -1.0.
-------------------------------------
#include <stdio.h>
int main() {
double x = -1.0;
printf("%f\n",x);
return 0;
}
-------------------------------------
I believe the cause of the problem is the struct ldieee
defined in newlib/libc/stdio/vfieeefp.h is not "packed",
and in the function cvt in newlib/libc/stdio/vfieeefp.h
ld.ieee.sign does not get the proper sign.
When I change all the definitions of
struct ldieee
to
struct __attribute__ ((__packed__)) ldieee
I can get the right result at the test program.
vfieeefp.h:
-------------------------------------
#ifdef IEEE_8087
#if LDBL_MANT_DIG == 24
struct ldieee
{
unsigned manh:23;
unsigned exp:8;
unsigned sign:1;
};
#elif LDBL_MANT_DIG == 53
struct ldieee
{
unsigned manl:20;
unsigned manh:32;
unsigned exp:11;
unsigned sign:1;
};
#elif LDBL_MANT_DIG == 64
struct ldieee
{
unsigned manl:32;
unsigned manh:32;
unsigned exp:15;
unsigned sign:1;
};
#elif LDBL_MANT_DIG > 64
struct ldieee
{
unsigned manl3:16;
unsigned manl2:32;
unsigned manl:32;
unsigned manh:32;
unsigned exp:15;
unsigned sign:1;
};
...
--------------------------------------
vfprintf.c:
--------------------------------------
# else /* !_NO_LONGDBL */
union
{
struct ldieee ieee;
_LONG_DOUBLE val;
} ld;
ld.val = value;
if (ld.ieee.sign) { /* this will check for < 0 and -0.0 */
value = -value;
*sign = '-';
} else
*sign = '\000';
--------------------------------------
Shoichi Sakon
NEC Corp.