PATCH: (for) Re: Portability of idiom
Loren James Rittle
rittle@latour.rsch.comm.mot.com
Wed Jan 30 16:47:00 GMT 2002
>>> FAIL: 26_numerics/complex_inserters_extractors.cc execution test
>>> FAIL: 27_io/istream_sentry.cc execution test
>> Cool let's fix this up!
> OK, I will present a patch later today which merely changes the check
> of errno == 0 to be "errno not have any value set by called C
> library function as spec'd in C90/C99".
Rebuilt libstdc++-v3 from scratch on i386-unknown-freebsd5.0 and
i386-unknown-freebsd4.4. Fixes both quoted test cases on the first
machine with no regressions. I reviewed FreeBSD, Solaris 2.7 and OSF1
man pages and ISO C99. Unfortunately, the Solaris man page says:
``If no conversion could be performed, strtol() and strtoll() return 0
and errno may be set to EINVAL.'' (OSF1 similar)
Fortunately, both Solaris and OSF will only ever actually set this
non-standard errno, if base is out of range. We tightly control the
base setting in the library thus this difference need not be
conditionally checked per port (Solaris sets __sanity to __s anyways).
Since ERANGE is the only value mentioned in the specification, I check
for it alone.
In any event, given the nature of the change, I also rebuilt and
checked on sparc-sun-solaris2.7 (looking good) and alphaev67-dec-osf5.1
(26_numerics/complex_inserters_extractors.cc and 28 other tests still
fail for independent reasons) without regression.
I shant touch libstdc++-v3/config/locale/c_locale_gnu.cc since I
presume it knows all about the library implementation. It is using
special GNU libc entry points.
Installed on mainline. (Strictly speaking, not a regression from 3.0
thus should not be moved to branch.)
* config/locale/c_locale_generic.cc: Check errno for ERANGE
instead of non-zero to aid portability.
Index: libstdc++-v3/config/locale/c_locale_generic.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/c_locale_generic.cc,v
retrieving revision 1.6
diff -c -r1.6 c_locale_generic.cc
*** c_locale_generic.cc 2002/01/23 16:20:46 1.6
--- c_locale_generic.cc 2002/01/30 22:40:02
***************
*** 48,54 ****
char* __sanity;
errno = 0;
long __l = strtol(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __l;
else
__err |= ios_base::failbit;
--- 48,54 ----
char* __sanity;
errno = 0;
long __l = strtol(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __l;
else
__err |= ios_base::failbit;
***************
*** 65,71 ****
char* __sanity;
errno = 0;
unsigned long __ul = strtoul(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __ul;
else
__err |= ios_base::failbit;
--- 65,71 ----
char* __sanity;
errno = 0;
unsigned long __ul = strtoul(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __ul;
else
__err |= ios_base::failbit;
***************
*** 83,89 ****
char* __sanity;
errno = 0;
long long __ll = strtoll(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __ll;
else
__err |= ios_base::failbit;
--- 83,89 ----
char* __sanity;
errno = 0;
long long __ll = strtoll(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __ll;
else
__err |= ios_base::failbit;
***************
*** 100,106 ****
char* __sanity;
errno = 0;
unsigned long long __ull = strtoull(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __ull;
else
__err |= ios_base::failbit;
--- 100,106 ----
char* __sanity;
errno = 0;
unsigned long long __ull = strtoull(__s, &__sanity, __base);
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __ull;
else
__err |= ios_base::failbit;
***************
*** 124,130 ****
#else
float __f = static_cast<float>(strtod(__s, &__sanity));
#endif
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __f;
else
__err |= ios_base::failbit;
--- 124,130 ----
#else
float __f = static_cast<float>(strtod(__s, &__sanity));
#endif
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __f;
else
__err |= ios_base::failbit;
***************
*** 144,150 ****
char* __sanity;
errno = 0;
double __d = strtod(__s, &__sanity);
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __d;
else
__err |= ios_base::failbit;
--- 144,150 ----
char* __sanity;
errno = 0;
double __d = strtod(__s, &__sanity);
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __d;
else
__err |= ios_base::failbit;
***************
*** 165,171 ****
char* __sanity;
errno = 0;
long double __ld = strtold(__s, &__sanity);
! if (__sanity != __s && *__sanity == '\0' && errno == 0)
__v = __ld;
#else
typedef char_traits<char>::int_type int_type;
--- 165,171 ----
char* __sanity;
errno = 0;
long double __ld = strtold(__s, &__sanity);
! if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
__v = __ld;
#else
typedef char_traits<char>::int_type int_type;
More information about the Libstdc++
mailing list