Fix size_max macro
Hi, The size_max macro has a bug: it assumes that 'expr' can deal with numbers as large as SIZE_MAX/10. Which is not true when cross-compiling from a 32-bit platform to a 64-bit platform. Here is a fix, that takes care that SIZE_MAX is valid in preprocessor expressions (i.e. contains no casts). OK to commit? Bruno *** m4/size_max.m4 11 Jul 2005 11:29:40 - 1.4 --- m4/size_max.m4 13 Jun 2006 15:44:30 - *** *** 1,5 ! # size_max.m4 serial 3 ! dnl Copyright (C) 2003, 2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. --- 1,5 ! # size_max.m4 serial 4 ! dnl Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. *** *** 24,50 if test -z $result; then dnl Define it ourselves. Here we assume that the type 'size_t' is not wider dnl than the type 'unsigned long'. ! dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr', ! dnl which is guaranteed to work from LONG_MIN to LONG_MAX. ! _AC_COMPUTE_INT([(size_t)~(size_t)0 / 10], res_hi, ! [#include stddef.h], result=?) ! _AC_COMPUTE_INT([(size_t)~(size_t)0 % 10], res_lo, ! [#include stddef.h], result=?) _AC_COMPUTE_INT([sizeof (size_t) = sizeof (unsigned int)], fits_in_uint, ! [#include stddef.h], result=?) ! if test $fits_in_uint = 1; then ! dnl Even though SIZE_MAX fits in an unsigned int, it must be of type ! dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. ! AC_TRY_COMPILE([#include stddef.h ! extern size_t foo; ! extern unsigned long foo; ! ], [], fits_in_uint=0) ! fi ! if test -z $result; then ! if test $fits_in_uint = 1; then ! result=$res_hi$res_loU else ! result=$res_hi$res_loUL fi else dnl Shouldn't happen, but who knows... --- 24,50 if test -z $result; then dnl Define it ourselves. Here we assume that the type 'size_t' is not wider dnl than the type 'unsigned long'. ! _AC_COMPUTE_INT([sizeof (size_t) * CHAR_BIT - 2], size_t_bits_minus_2, ! [#include stddef.h ! #include limits.h], size_t_bits_minus_2=) _AC_COMPUTE_INT([sizeof (size_t) = sizeof (unsigned int)], fits_in_uint, ! [#include stddef.h], fits_in_uint=) ! if test -n $size_t_bits_minus_2 test -n $fits_in_uint; then ! if test $fits_in_uint = 1; then ! dnl Even though SIZE_MAX fits in an unsigned int, it must be of type ! dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. ! AC_TRY_COMPILE([#include stddef.h ! extern size_t foo; ! extern unsigned long foo; ! ], [], fits_in_uint=0) ! fi ! dnl We cannot use 'expr' to simplify this expression, because 'expr' ! dnl works only with 'long' integers in the host environment, while we ! dnl might be cross-compiling from a 32-bit platform to a 64-bit platform. ! if test $fits_in_uint = 1; then ! result=(((1U $size_t_bits_minus_2) - 1) * 2 + 1) else ! result=(((1UL $size_t_bits_minus_2) - 1) * 2 + 1) fi else dnl Shouldn't happen, but who knows...
Re: stdint module rewrite
Is there anything in this that would enable me to install a stdint.h file in $prefix (called something like idn-int.h), so I can use uint32_t etc in my API, and be backwards compatible with hosts that doesn't have uint32_t natively? Compare the AX_CREATE_STDINT_H macro: http://autoconf-archive.cryp.to/ax_create_stdint_h.html The essential difference is that the installed idn-int.h should work without assuming any config.h symbols, but instead rely on a combination of install-time guesses and CPP symbol checks to define the proper uint32_t types for the host and the compilers on that host. Thanks.
Re: csharpcomp: cscc writes to srcdir?
Bruno Haible [EMAIL PROTECTED] writes: Should csharpcomp copy the *.cs file before compilation, perhaps? I fully agree with your analysis and opinion. A compiler should not write temporary files in the source nor in the target directory. That's what $TMPDIR (or /tmp if unset) is made for. IMO it's worth filing a bug report. Should csharpcomp copy the *.cs file before compilation, perhaps? IMO the compiler itself (cscc) should not do such things in the first place. I've filed a bug with Debian about this: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=372697 /Simon
Re: Fix size_max macro
The basic idea seems fine, but isn't that off by a factor of 2? It defines size_t_bits_minus_2 = sizeof (size_t) * CHAR_BIT - 2 and then defines SIZE_MAX to (((1U $size_t_bits_minus_2) - 1) * 2 + 1). Unless I'm missing something, on a 32-bit host, that will set SIZE_MAX to 2147483647 instead of the correct value. Instead, how about if we compute size_t_bits = sizeof (size_t) * CHAR_BIT and then define SIZE_MAX to (((1U ($size_t_bits - 1)) - 1) * 2 + 1)?
Re: Fix size_max macro
Paul Eggert wrote: The basic idea seems fine, but isn't that off by a factor of 2? It defines size_t_bits_minus_2 = sizeof (size_t) * CHAR_BIT - 2 and then defines SIZE_MAX to (((1U $size_t_bits_minus_2) - 1) * 2 + 1). Unless I'm missing something, on a 32-bit host, that will set SIZE_MAX to 2147483647 instead of the correct value. Oops, you're right, of course. The minus 2 is for a signed type. The formula for an unsigned type is minus 1. Thanks, I'm correcting it. Bruno
Re: stdint module rewrite
Simon Josefsson wrote: Is there anything in this that would enable me to install a stdint.h file in $prefix We could just need to change all #if HAVE_... into #if @HAVE_...@ and use more substitutions in the creation of the stdint.h file. But there are two problems: - It's compiler dependent. On the same platform, a compiler can have uint32_t (or 'long long' etc.) and another can lack it. - Even with the same compiler, the choice of the int_fastN_t types is arbitrary. Another person might create an stdint.h that defines them differently. (called something like idn-int.h) Why not call it stdint.h? Compare the AX_CREATE_STDINT_H macro: http://autoconf-archive.cryp.to/ax_create_stdint_h.html The essential difference is that the installed idn-int.h should work without assuming any config.h symbols, but instead rely on a combination of install-time guesses and CPP symbol checks to define the proper uint32_t types for the host and the compilers on that host. Sorry, I cannot see how a CPP symbol test can tell whether uint32_t is defined, if I don't know the compiler a priori. And #ifdefs of known systems is not the right approach - not autoconfiguring, hard to maintain. Bruno
Re: stdint module rewrite
Bruno Haible [EMAIL PROTECTED] writes: Here is a proposed rewrite of the stdint module. It defines a *complete* stdint.h, and is autoconfiguring - no more #ifdef __FreeBSD__ etc. that are hard to maintain. It appears to work fine on Solaris and HP-UX IA64. The only downside is that it bloats up 'configure' - but autoconf 3 should annihilate that growth, I'm told. Autoconf 3 won't be out for quite some time, I'm afraid. The approach assumes a conventional architecture in which there are underyling signed and unsigned types of width 8, 16, 32, and 64, and the only argument is which int*_t type is which. That's likely the only case worth worrying about, for backward compatibility reasons anyway. How about simplifying things as follows? 1. If the system stdint.h doesn't work, we omit it entirely, and substitute our own entirely. 2. We work around incompatibilities between our substitute and the standard header files by having our stdint.h substitute do this first: #define int_fast32_t rpl_int_fast32_t #define int_fast64_t rpl_int_fast64_t ... [include sys/inttypes.h, FULL_PATH_INTTYPES_H, etc., here] #undef int_fast32_t #undef int_fast64_t ... #undef INT_FAST32_MIN #undef INT_FAST32_MAX #undef INT_FAST64_MIN #undef INT_FAST64_MAX An advantage of this approach is that we will work around subtle bugs in existing implementations, if ours is good. For example, on Solaris 10, UINT16_MAX is (65535U) which is incorrect; it's supposed to be a signed value. (Both the current and the proposed stdint.h have the same bug, but we can fix it. :-) Another advantage is that it won't require many Autoconf tests; basically, whether 'long' is 32 or 64 bits, and whether 'long long' is available (we can assume it's 64 bits, I suppose). A disadvantage of this approach is that if our opinion of int_fast32_t disagrees with that of the (broken) system file, and if some other system header uses int_fast32_t, then we could be hosed.
Re: stdint module rewrite (was: Re: Build CVS (TRUNK) failed.)
* Bruno Haible wrote on Tue, Jun 13, 2006 at 06:20:18PM CEST: The only downside is that it bloats up 'configure' - but autoconf 3 should annihilate that growth, I'm told. You should be able to rewrite this to use shell loops for the most part; similar to how I started in this thread: http://lists.gnu.org/archive/html/autoconf-patches/2006-04/msg00161.html but never finished the last bits. Without the rewrite of macros to work with shell variables, even Autoconf 3 won't be able to save you. Cheers, Ralf
Re: stdint module rewrite
Paul Eggert wrote: The approach assumes a conventional architecture in which there are underyling signed and unsigned types of width 8, 16, 32, and 64, and the only argument is which int*_t type is which. Yes, and it does so using the approach use what the system provides, and define a substitute only for the lacking entities. 1. If the system stdint.h doesn't work, we omit it entirely, and substitute our own entirely. 2. We work around incompatibilities between our substitute and the standard header files by having our stdint.h substitute do this first: #define int_fast32_t rpl_int_fast32_t #define int_fast64_t rpl_int_fast64_t ... [include sys/inttypes.h, FULL_PATH_INTTYPES_H, etc., here] #undef int_fast32_t #undef int_fast64_t ... #undef INT_FAST32_MIN #undef INT_FAST32_MAX #undef INT_FAST64_MIN #undef INT_FAST64_MAX Uuh. As you already noted yourself, the danger here with these approaches is that when you link a file compiled with the original stdint.h and a file compiled with our substitute, mismatch can occur. For example, a function taking a int_fast8_t * argument. I've once debugged a program where a header file declared a variable of type int (*) (const char *, struct stat *) and part of the program was compiled with _FILE_OFFSET_BITS=64 (implying stat := stat64) and another part of the program without it. I don't want to debug similar mistakes again. For example, on Solaris 10, UINT16_MAX is (65535U) which is incorrect; it's supposed to be a signed value. (Both the current and the proposed stdint.h have the same bug, but we can fix it. :-) Ouch, I didn't notice that requirement. Thanks. Bruno
Re: stdint module rewrite
Bruno Haible [EMAIL PROTECTED] writes: I've once debugged a program where a header file declared a variable of type int (*) (const char *, struct stat *) and part of the program was compiled with _FILE_OFFSET_BITS=64 (implying stat := stat64) and another part of the program without it. I don't want to debug similar mistakes again. We can't solve that problem in general, since (as you note) different compilers on the same platform (or even the same compiler, with different options) might disagree about the standard types. So it's not an issue of solving the problem in general; it's an issue of how likely it would occur in practice, with the approach I proposed. I think the problem unlikely and not worth worrying about. The only types for which it's at all likely that there will be disagreement are int_fast32_t and friends, and these are rarely used by other standard headers, particularly on platforms that don't have a conforming stdint.h. On Solaris 10, for example, the *int_fast* types are not used by any other standard header.
Re: stdint module rewrite (was: Re: Build CVS (TRUNK) failed.)
Ralf Wildenhues wrote: You should be able to rewrite this to use shell loops for the most part; similar to how I started in this thread: http://lists.gnu.org/archive/html/autoconf-patches/2006-04/msg00161.html but never finished the last bits. Actually, that's how I started doing it: for type in int8_t int16_t int32_t int64_t \ uint8_t uint16_t uint32_t uint64_t \ int_least8_t int_least16_t int_least32_t int_least64_t \ uint_least8_t uint_least16_t uint_least32_t uint_least64_t \ int_fast8_t int_fast16_t int_fast32_t int_fast64_t \ uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t \ intptr_t uintptr_t \ intmax_t uintmax_t ; do AC_MSG_CHECKING([for $type]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([$other_includes /* Test if the type exists. */ $type x = 17; ])], result=yes, result=no) eval gl_cv_type_${type}=\$result AC_MSG_RESULT($result) if test $result = yes; then TYPE=`echo $type | sed -e y/aefilmnprstux/AEFILMNPRSTUX/` AC_DEFINE_UNQUOTED(HAVE_${TYPE}, 1, [Define to 1 if the type '$type' is already defined.]) fi done But this way, autoheader didn't recognise the AC_DEFINE_UNQUOTED invocations, i.e. in the end, HAVE_INT8_T etc. were not present in config.h.in. Without the rewrite of macros to work with shell variables, even Autoconf 3 won't be able to save you. Ouch. I imagined most of the autoconf built-in macro invocations would be transformed into a single shell function call. Is this not the plan? Bruno
Re: stdint module rewrite
Paul Eggert wrote: the same compiler, with different options) might disagree about the standard types. So it's not an issue of solving the problem in general; it's an issue of how likely it would occur in practice, with the approach I proposed. We are not the only people providing a stdint.h substitute. There are at least two other ones, plus the system stdint.h. The problem will occur as soon as these types int_fastN_t are used in header files and - through different -I options - the compiler will not always pick the same stdint.h. Different -I options in different directories of a large package are quite frequent. It may simply be a -I/usr/include which causes the system's stdint.h to take precedence. By not redefining types that are already defined by the system, I can not avoid clashes between our stdint.h substitute and the two other portable ones, but at least I can avoid clashes with the system headers. I'll add a warning to the stdint.h substitute, not to use the int_fastN_t types in header files. Bruno
Re: add gmp library dependency; get dist to work...
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 [Adding bug-gnulib] According to Eric Blake-1 on 6/13/2006 10:50 AM: Hi Ralf, (and yes, in order to be able to even get `make' to succeed, I need to fiddle with gnulib getopt currently; __getopt_argv_const is not #defined in my system getopt.h, but it's used unconditionally in src/getopt1.c). Can you report that to gnulib? It looks like the getopt module may have a bug. Ralf, which system were you on where the system getopt.h failed with gnulib getopt1.c? - -- Life is short - so eat dessert first! Eric Blake [EMAIL PROTECTED] -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.2.1 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEj1mX84KuGfSFAYARAoqrAKCj3ip9z96m0g2P2VhJgFSX1ICh6QCffcVR R2+P1mNmP9s9SQycPwbZRtk= =V3Ns -END PGP SIGNATURE-
Re: regex.c not 64-bit clean (?)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Hi Santiago, [adding bug-gnulib, dropping bug-m4] According to Santiago Vila on 6/12/2006 12:07 PM: I suspect it will be, since I really haven't touched regex.c that much since 1.4.4. Then try this patch which pulls the latest regex.c from gnulib: $ make clean $ patch -p0 email $ GNULIB_TOOL=../gnulib/gnulib-tool ./bootstrap $ ./configure CFLAGS='-Wall -Werror' $ make This is what happens: make all-recursive make[1]: Entering directory `/home/sanvila/tmp/m4' Making all in examples make[2]: Entering directory `/home/sanvila/tmp/m4/examples' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/home/sanvila/tmp/m4/examples' Making all in lib make[2]: Entering directory `/home/sanvila/tmp/m4/lib' cp ./alloca_.h alloca.h-t mv alloca.h-t alloca.h make all-am make[3]: Entering directory `/home/sanvila/tmp/m4/lib' gcc -DHAVE_CONFIG_H -I. -I. -I.. -Wall -Werror -c strnlen1.c gcc -DHAVE_CONFIG_H -I. -I. -I.. -Wall -Werror -c xalloc-die.c In file included from /usr/include/stdlib.h:433, from xalloc-die.c:26: /usr/include/sys/types.h:110: error: two or more data types in declaration specifiers make[3]: *** [xalloc-die.o] Error 1 Sounds like we have a gnulib bug on our hands, in xalloc-die. OK, remind me again what 'uname -a', 'gcc --version', and 'config.guess' report. Also, what does 'sed -ne 90,110p /usr/include/sys/types.h' show? Really nice would be narrowing in on what the preprocessor saw: $ cd lib $ gcc -E -DHAVE_CONFIG_H -I. -I.. xalloc-die.c and figure where in the output that line from stdlib was showing up. This is on a debian machine with architecture ia64. Unfortunately, I am not root, so I can't change anything in the build environment (in fact I've had to do the cvs and bootstrap parts in another machine). Meanwhile, the original question was whether the gnulib version of regex.c solved the 64-bit bugs present in the years-old version that m4 1.4.4 used. Now that you have gnulib checked out, try: $ cd gnulib $ CFLAGS='-Wall -Werror' gnulib-tool --test regex and see if that compiles cleanly. If so, I can go ahead and commit my patch to use gnulib for m4 1.4.5. - -- Life is short - so eat dessert first! Eric Blake [EMAIL PROTECTED] -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.2.1 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEj1nr84KuGfSFAYARAseSAJ9GmOjS9eV/MxgUSXYTajX/o3SO6QCffDA4 8VvHE257xNsctjBb0sGo4oo= =WRUD -END PGP SIGNATURE-
Re: stdint module rewrite (was: Re: Build CVS (TRUNK) failed.)
* Bruno Haible wrote on Tue, Jun 13, 2006 at 11:00:45PM CEST: Ralf Wildenhues wrote: You should be able to rewrite this to use shell loops for the most part; Actually, that's how I started doing it: But this way, autoheader didn't recognise the AC_DEFINE_UNQUOTED invocations, i.e. in the end, HAVE_INT8_T etc. were not present in config.h.in. Yes, but that's basically the only part that breaks this way. And only one part of the AC_DEFINE_UNQUOTED, namely the part that needs to be traceable for autoheader: the AH_TEMPLATE call. So you can split the macro in the same way that AC_CHECK_HEADERS uses. Without the rewrite of macros to work with shell variables, even Autoconf 3 won't be able to save you. Ouch. I imagined most of the autoconf built-in macro invocations would be transformed into a single shell function call. Is this not the plan? Sure this is the plan; but you have to be able to rewrite the built-in macro into a shell function in the first place; this won't work for AH_TEMPLATE, only for the rest. This means that, even if Autoconf 3 may be able to reduce the size of the expansion by some amount, it won't be able to beat the size you can achieve by writing a shell loop in the first place, because there will still be a nontrivial amount of expansion per function call. Cheers, Ralf