[adding bug-autoconf] On 06/13/2010 05:43 PM, Bruno Haible wrote: > Hi Ben, > >> The problem is that AC_FUNC_STRTOD assumes that strtod does not >> exist when cross-compiling, which in turn makes the strtod module >> assume that it does not need to handle an existing declaration. > > Ah, so AC_FUNC_STRTOD makes gnulib think that strtod() does not exist, > although in fact it does exist. Just because of the worst-case guess > that says "ac_cv_func_strtod=no". > > - When we are cross-compiling, we should avoid pessimistic guesses > such as "ac_cv_func_strtod=no". The reason is that the most frequent > use of cross-compiling is done for embedded Linux devices (devices > with BusyBox, or everything-on-a-chip systems). In such cases, > it is not well seen if gnulib provides a replacement function when > in fact it is not needed at all. So, please, when cross-compiling, > give a thought to the embedded Linux case (with glibc or uClibc). > > So: Do current embedded Linuxes have the strtod bugs or not? Take a > look at the AC_FUNC_STRTOD macro in autoconf/lib/autoconf/functions.m4: > > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1537)# > AC_FUNC_STRTOD > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1538)# > -------------- > 7134f17d (Akim Demaille 2002-09-28 14:06:07 +0000 > 1539)AN_FUNCTION([strtod], [AC_FUNC_STRTOD]) > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 > 1540)AC_DEFUN([AC_FUNC_STRTOD], > 1492d7c5 (Akim Demaille 2001-11-12 15:47:35 +0000 > 1541)[AC_SUBST(POW_LIB)dnl > 1492d7c5 (Akim Demaille 2001-11-12 15:47:35 +0000 > 1542)AC_CACHE_CHECK(for working strtod, ac_cv_func_strtod, > 6a2a74c2 (Akim Demaille 2001-07-04 14:37:52 +0000 > 1543)[AC_RUN_IFELSE([AC_LANG_SOURCE([[ > 11ee0ab5 (Paul Eggert 2004-05-03 20:15:44 +0000 > 1544)]AC_INCLUDES_DEFAULT[ > 11ee0ab5 (Paul Eggert 2004-05-03 20:15:44 +0000 1545)#ifndef > strtod > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1546)double > strtod (); > 11ee0ab5 (Paul Eggert 2004-05-03 20:15:44 +0000 1547)#endif > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1548)int > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1549)main() > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1550){ > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1551) { > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1552) /* > Some versions of Linux strtod mis-parse strings with leading '+'. */ > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1553) char > *string = " +69"; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1554) char > *term; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1555) > double value; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1556) > value = strtod (string, &term); > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1557) if > (value != 69 || term != (string + 4)) > a71c24a7 (Paul Eggert 2006-04-03 03:18:39 +0000 1558) > return 1; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1559) } > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1560) > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1561) { > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1562) /* > Under Solaris 2.4, strtod returns the wrong value for the > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1563) > terminating character under some conditions. */ > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1564) char > *string = "NaN"; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1565) char > *term; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1566) > strtod (string, &term); > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1567) if > (term != string && *(term - 1) == 0) > a71c24a7 (Paul Eggert 2006-04-03 03:18:39 +0000 1568) > return 1; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1569) } > a71c24a7 (Paul Eggert 2006-04-03 03:18:39 +0000 1570) return > 0; > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1571)} > 6a2a74c2 (Akim Demaille 2001-07-04 14:37:52 +0000 1572)]])], > b44e483c (Akim Demaille 2003-05-17 10:30:07 +0000 1573) > ac_cv_func_strtod=yes, > b44e483c (Akim Demaille 2003-05-17 10:30:07 +0000 1574) > ac_cv_func_strtod=no, > b44e483c (Akim Demaille 2003-05-17 10:30:07 +0000 1575) > ac_cv_func_strtod=no)]) > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1576)if test > $ac_cv_func_strtod = no; then > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1577) > _AC_LIBOBJ_STRTOD > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1578)fi > 7bd04c77 (Akim Demaille 2000-08-01 11:16:33 +0000 1579)]) > > With two old old old tests and no reasonable cross-compiling behaviour I > would say that the best thing to do is to move these two blocks of C code > into gl_FUNC_STRTOD's test, and stop using AC_FUNC_STRTOD. Then the > autoconf documentation can mark this macro obsolescent, and on the gnulib > side this test runs one program, not two, and we have full control over > the cross-compilation behaviour.
Or even better, why not push those two tests upstream into autoconf, then have gnulib override AC_FUNC_STRTOD if it detects older autoconf, so that everyone using upstream AC_FUNC_STRTOD can reliably detect these same bugs? > @@ -28,6 +34,24 @@ > } > ]], [[ > { > + /* In some old versions of Linux (2000 or before), strtod mis-parses > + strings with leading '+'. */ > + const char *string = " +69"; > + char *term; > + double value = strtod (string, &term); > + if (value != 69 || term != (string + 4)) > + return 1; > + } > + { > + /* Under Solaris 2.4, strtod returns the wrong value for the > + terminating character under some conditions. */ > + const char *string = "NaN"; > + char *term; > + strtod (string, &term); > + if (term != string && *(term - 1) == 0) > + return 1; > + } > + { > /* Older glibc and Cygwin mis-parse "-0x". */ > const char *string = "-0x"; > char *term; > > > -- Eric Blake ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature