wbirkett has asked for the wisdom of the Perl Monks concerning the following question:

The following code is used in an XS to make an array full of 0's. It works fine.

/* create a Perl array filled with zeros */ SV* vec_zeros(int m) { int i; AV *myav; SV **svs; /* allocate memory for array */ *svs = (SV **) malloc(m * sizeof(SV *)); /* for m array elements */ for (i = 0; i < m; i++) { /* create a Perl SV (scalar value) */ svs[i] = sv_newmortal(); /* set SV to 0 */ sv_setnv((SV*)svs[i], 0.0f); } /* make Perl AV */ myav = av_make(m, svs); /* free allocated memory */ free(svs); /* return array reference */ return newRV_noinc((SV*) myav); }

Heeding advice in 'perlguts', I changed 'malloc' to 'Newx' and 'free' to 'Safefree'

/* create a Perl array filled with zeros */ SV* vec_zeros(int m) { int i; AV *myav; SV **svs; /* allocate memory for array */ Newx(svs, m, SV *); /* for m array elements */ for (i = 0; i < m; i++) { /* create a Perl SV (scalar value) */ svs[i] = sv_newmortal(); /* set SV to 0 */ sv_setnv((SV*)svs[i], 0.0f); } /* make Perl AV */ myav = av_make(m, svs); /* free allocated memory */ Safefree(svs); /* return array reference */ return newRV_noinc((SV*) myav); }

Now I get the following warnings when I compile:

xs_arrays.c: In function ‘vec_zeros’: xs_arrays.c:247: warning: format not a string literal and no format ar +guments xs_arrays.c: In function ‘vec_zeros’: xs_arrays.c:247: warning: format not a string literal and no format ar +guments xs_arrays.c: In function ‘vec_zeros’: xs_arrays.c:247: warning: format not a string literal and no format ar +guments

Any idea what this means, and how to correct it? I'm using Perl 5.10.0, as supplied on Mac OS X:

Summary of my perl5 (revision 5 version 10 subversion 0) configuration +: Platform: osname=darwin, osvers=10.0, archname=darwin-thread-multi-2level uname='darwin neige.apple.com 10.0 darwin kernel version 10.0.0d8: + tue may 5 19:29:59 pdt 2009; root:xnu-1437.2~2release_i386 i386 ' config_args='-ds -e -Dprefix=/usr -Dccflags=-g -pipe -Dldflags= +-Dman3ext=3pm -Duseithreads -Duseshrplib -Dinc_version_list=none -Dcc +=gcc-4.2' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und +ef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc-4.2', ccflags ='-arch x86_64 -arch i386 -arch ppc -g -pipe + -fno-common -DPERL_DARWIN -fno-strict-aliasing -I/usr/local/include' +, optimize='-Os', cppflags='-g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing +-I/usr/local/include' ccversion='', gccversion='4.2.1 (Apple Inc. build 5646)', gccosand +vers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1 +6 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', + lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc-4.2 -mmacosx-version-min=10.6', ldflags ='-arch x86_64 -ar +ch i386 -arch ppc -L/usr/local/lib' libpth=/usr/local/lib /usr/lib libs=-ldbm -ldl -lm -lutil -lc perllibs=-ldl -lm -lutil -lc libc=/usr/lib/libc.dylib, so=dylib, useshrplib=true, libperl=libpe +rl.dylib gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-arch x86_64 -arch i386 -arch ppc -bund +le -undefined dynamic_lookup -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_ +BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API Locally applied patches: /Library/Perl/Updates/<version> comes before system perl directori +es installprivlib and installarchlib points to the Updates directory Built under darwin Compiled at Jun 24 2009 00:35:27 @INC: /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0

Replies are listed 'Best First'.
Re: Newx compiler warnings
by Eliya (Vicar) on Mar 19, 2011 at 15:02 UTC
    xs_arrays.c:247: warning: format not a string literal and no format arguments

    Normally, gcc issues this warning if *printf functions are being called with a non-literal first argument, and the respective warnings are enabled. (See also -Wformat, -Wformat-nonliteral, -Wformat-security in the gcc man page)  For example

    #include <stdio.h> int main() { char foo[100]; scanf("%s", foo); printf(foo); /* compiler cannot inspect contents of foo */ return 0; }
    $ gcc -Wformat -Wformat-security nonlit.c nonlit.c: In function 'main': nonlit.c:5: warning: format not a string literal and no format argumen +ts

    It seems those warnings were enabled by default in gcc 4.2.1 (with my newer version I explicitly have to request them).

    That said, I'm not sure where there would be something printf-related in your code... What is line 247?   Even the preprocessor expansion1 of your snippet reveals no (s|f)printf whatsoever:

    SV* vec_zeros(int m) { int i; AV *myav; SV **svs; (svs = ((void)(sizeof(SV *) > 1 && (m) > ((size_t)~0)/sizeof(SV *) + && (Perl_croak_nocontext(PL_memory_wrap),0)), (SV **)Perl_safesysmal +loc((size_t)((m)*sizeof(SV *))))); for (i = 0; i < m; i++) { svs[i] = Perl_sv_newmortal(((PerlInterpreter *)pthread_getspec +ific((*Perl_Gthr_key_ptr(((void *)0)))))); Perl_sv_setnv(((PerlInterpreter *)pthread_getspecific((*Perl_G +thr_key_ptr(((void *)0))))), (SV*)svs[i],0.0f); } myav = Perl_av_make(((PerlInterpreter *)pthread_getspecific((*Perl +_Gthr_key_ptr(((void *)0))))), m,svs); Perl_safesysfree((void *)(svs)); return Perl_newRV_noinc(((PerlInterpreter *)pthread_getspecific((* +Perl_Gthr_key_ptr(((void *)0))))), (SV*) myav); }

    Anyhow, most likely, you can just ignore the warning, or disable it with -Wno-format.

    ___

    1 done with gcc option -E, on a Linux system, with a perl built with "usemymalloc=n" (like yours).

      Perl_croak_nocontext() is marked as being 'printf'-like, so it will generate similar warnings. The definition of the Newx macro (or rather the underlying MEM_WRAP_CHECK_1 macro) was fixed in 5.12.0 to avoid this (harmless) warning.

      Dave.