On Sat, 18 Jun 2005 18:51:40 +0100, Nicholas Clark <[EMAIL PROTECTED]> wrote:
> Is this a suitable patch to apply to Configure (and backport to the > metaconfig units), for the purpose of testing whether 0.0 is stored as all > bits zero in memory? It's a useful thing to know, because if it's true > (which I think is generally the case), then memset of a block of memory to > 0 is sufficient to correctly initialise any NVs that it contains. It's > quite safe for it to default to #undef on non-Configure platforms. Looks complete and correct. I wonder if the debug messages in the test program should go to stderr instead. Feel free to commit. I have to backport to a new meta-unit and check deps, and I don't know how long it would take. IF you commit, don't hesitate to also USE the define somewhere in the core code, since I must otherwise (ab)use handy.h again to make the new unit to be included in Configure, since metaconfig will skit the unit if the things it defines are not used anywhere > In theory we should also be checking that NULL pointers are stored as all > bits zero, but I think that that portability battle is already lost - we > already Zero() SV bodies that contain pointers and expect things to work. > > Also, I think that by adding another symbol to config_h.SH this breaks VMS, > but I can't remember the correct fix, or where it goes. Can someone help? > > Nicholas Clark > > > --- Configure.orig Tue May 31 07:09:02 2005 > +++ Configure Sat Jun 18 17:55:48 2005 > @@ -1002,6 +1002,7 @@ perl5='' > perladmin='' > perlpath='' > d_nv_preserves_uv='' > +d_nv_zero_is_allbits_zero='' > i16size='' > i16type='' > i32size='' > @@ -14833,6 +14834,128 @@ esac > > $rm -f try.* try > > +$echo "Checking whether NV 0.0 is all bits zero in memory..." >&4 > +: volatile so that the compiler has to store it out to memory. > +if test X"$d_volatile" = X"$define"; then > + volatile=volatile > +fi > +$cat <<EOP >try.c > +#include <stdio.h> > +#$i_stdlib I_STDLIB > +#ifdef I_STDLIB > +#include <stdlib.h> > +#endif > +#$i_string I_STRING > +#ifdef I_STRING > +# include <string.h> > +#else > +# include <strings.h> > +#endif > +#include <sys/types.h> > +#include <signal.h> > +#ifdef SIGFPE > +$volatile int bletched = 0; > +$signal_t blech(s) int s; { bletched = 1; } > +#endif > + > +int checkit($nvtype d, char *where) { > + unsigned char *p = (char *)&d; > + unsigned char *end = p + sizeof(d); > + int fail = 0; > + > + while (p < end) > + fail += *p++; > + > + if (!fail) > + return 0; > + > + p = (char *)&d; > + printf("No - %s: 0x", where); > + while (p < end) > + printf ("%02X", *p++); > + printf("\n"); > + return 1; > +} > + > +int main(int argc, char **argv) { > + $nvtype d = 0.0; > + int fail = 0; > + fail += checkit(d, "0.0"); > + > + /* The compiler shouldn't be assuming that bletched is 0 */ > + d = bletched; > + > + fail += checkit(d, "bleched"); > + > +#ifdef SIGFPE > + signal(SIGFPE, blech); > +#endif > + > + /* Paranoia - the compiler should have no way of knowing that ANSI says > + that argv[argc] will always be NULL. Actually, if it did assume > this it > + would be buggy, as this is C and main() can be called from > elsewhere in > + the program. */ > + d = argv[argc] ? 1 : 0; > + > + if (d) { > + printf("Odd argv[argc]=%p, d=%g\n", argv[argc], d); > + } > + > + fail += checkit(d, "ternary"); > + > + memset(&d, sizeof(d), argv[argc] ? 1 : 0); > + > + if (d != 0.0) { > + printf("No - memset doesn't give 0.0\n"); > + /* This might just blow up: */ > + printf("(gives %g)\n", d); > + return 1; > + } > + > +#ifdef SIGFPE > + if (bletched) { > + printf("No - something bleched\n"); > + return 1; > + } > +#endif > + if (fail) { > + printf("No - %d fail(s)\n", fail); > + return 1; > + } > + printf("Yes\n"); > + return 0; > +} > +EOP > +set try > + > +d_nv_zero_is_allbits_zero="$undef" > +if eval $compile; then > + xxx="`$run ./try`" > + case "$?" in > + 0) > + case "$xxx" in > + Yes) cat >&4 <<EOM > +0.0 is represented as all bits zero in memory > +EOM > + d_nv_zero_is_allbits_zero="$define" > + ;; > + *) cat >&4 <<EOM > +0.0 is not represented as all bits zero in memory > +EOM > + d_nv_zero_is_allbits_zero="$undef" > + ;; > + esac > + ;; > + *) cat >&4 <<EOM > +0.0 is not represented as all bits zero in memory > +EOM > + d_nv_zero_is_allbits_zero="$undef" > + ;; > + esac > +fi > + > +$rm -f try.* try > + > > : check for off64_t > echo " " > @@ -21012,6 +21135,7 @@ d_mymalloc='$d_mymalloc' > d_nice='$d_nice' > d_nl_langinfo='$d_nl_langinfo' > d_nv_preserves_uv='$d_nv_preserves_uv' > +d_nv_zero_is_allbits_zero='$d_nv_zero_is_allbits_zero' > d_off64_t='$d_off64_t' > d_old_pthread_create_joinable='$d_old_pthread_create_joinable' > d_oldpthreads='$d_oldpthreads' > --- config_h.SH.orig Thu May 26 12:56:06 2005 > +++ config_h.SH Sat Jun 18 17:31:21 2005 > @@ -3235,6 +3235,10 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#und > * This symbol contains the number of bits a variable of type NVTYPE > * can preserve of a variable of type UVTYPE. > */ > +/* NV_ZERO_IS_ALLBITS_ZERO > + * This symbol, if defined, indicates that a variable of type NVTYPE > + * stores 0.0 in memory as all bits zero. > + */ > #define IVTYPE $ivtype /**/ > #define UVTYPE $uvtype /**/ > #define I8TYPE $i8type /**/ > @@ -3263,6 +3267,7 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#und > #define NVSIZE $nvsize /**/ > #$d_nv_preserves_uv NV_PRESERVES_UV > #define NV_PRESERVES_UV_BITS $nv_preserves_uv_bits > +#$d_nv_zero_is_allbits_zero NV_ZERO_IS_ALLBITS_ZERO > #if UVSIZE == 8 > # ifdef BYTEORDER > # if BYTEORDER == 0x1234 > --- Porting/Glossary.orig Fri May 20 09:23:14 2005 > +++ Porting/Glossary Sat Jun 18 17:32:22 2005 > @@ -1383,6 +1383,10 @@ d_nv_preserves_uv (perlxv.U): > This variable indicates whether a variable of type nvtype > can preserve all the bits a variable of type uvtype. > > +d_nv_zero_is_allbits_zero (perlxv.U): > + This variable indicates whether a variable of type nvtype > + stores 0.0 in memory as all bits zero. > + > d_off64_t (d_off64_t.U): > This symbol will be defined if the C compiler supports off64_t. > > -- H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/) using Perl 5.6.2, 5.8.0, 5.8.5, & 5.9.2 on HP-UX 10.20, 11.00 & 11.11, AIX 4.3 & 5.2, SuSE 9.2 & 9.3, and Cygwin. http://www.cmve.net/~merijn Smoking perl: http://www.test-smoke.org, perl QA: http://qa.perl.org reports to: [EMAIL PROTECTED], perl-qa@perl.org