> > On Tuesday 2008-12-16 17:05, Michel Van den Bergh wrote: > >> Hi, >> >> The following program segfaults when compiled with gcc >> but runs fine when compiled with g++ or icc (the intel C compiler) >> >> #include <stdio.h> >> struct Hello { >> char world[20]; >> }; >> struct Hello s(){ >> struct Hello r; >> r.world[0]='H'; >> r.world[1]='\0'; >> return r; >> } >> >> int main(){ >> printf("%s\n",s().world); >> } >> >> Assigning s() to a variable and then using the variable avoids the >> segfault. > > Had you compiled with -Wall would you have noticed: > > e.c:13: warning: format â%sâ expects type âchar *â, but > argument 2 has type âchar[20]â > > And when there is a type mismatch, a crash is pretty likely. > Not that I can say why gcc does not convert it to char* but g++ does. > > Now what happens? The following augmented snippet shows it: > ---<8--- > #include <stdarg.h> > #include <stdio.h> > #include <string.h> > struct Hello { > char world[20]; > }; > struct Hello s(void) > { > struct Hello r; > strcpy(r.world, "Hello"); > return r; > } > static void dump(const char *fmt, ...) > { > va_list argp; > va_start(argp, fmt); > char *p = va_arg(argp, char *); > printf("%p\n", p); > va_end(argp); > } > int main(void) > { > dump("", s().world); > return 0; > } > --->8--- > > I get 0x6c6c6548, which is obviously part of the string Hello. So > passing a char[20] into a varargs function seems not to convert it to > char* when done through a non-visibile temporary (the result of s() > is hidden on the stack of main).
On a baseline test machine ( Solaris 8 sun4m ) I get this with GCC 4.3.2 : $ gcc -o foo2_gcc foo2.c foo2.c: In function 'dump': foo2.c:16: error: '__builtin_va_alist' undeclared (first use in this function) foo2.c:16: error: (Each undeclared identifier is reported only once foo2.c:16: error: for each function it appears in.) If I use very very old Sun Studio 8 I get this : $ /opt/SUNWspro/bin/cc -V cc: Sun C 5.5 Patch 112760-19 2007/08/02 usage: cc [ options] files. Use 'cc -flags' for details $ /opt/SUNWspro/bin/cc -o foo2 foo2.c $ mcs -p foo2 foo2: @(#)stdarg.h 1.45 99/08/10 SMI @(#)stdarg_iso.h 1.1 99/08/09 SMI @(#)va_list.h 1.12 99/05/04 SMI @(#)stdio.h 1.78 99/12/08 SMI @(#)stdio_iso.h 1.2 99/10/25 SMI @(#)feature_tests.h 1.18 99/07/26 SMI @(#)isa_defs.h 1.20 99/05/04 SMI @(#)stdio_tag.h 1.3 98/04/20 SMI @(#)stdio_impl.h 1.8 99/06/10 SMI @(#)string.h 1.24 99/08/10 SMI @(#)string_iso.h 1.2 99/11/09 SMI acomp: Sun C 5.5 Patch 112760-19 2007/08/02 ld: Software Generation Utilities - Solaris Link Editors: 5.8-1.302 $ ./foo2 effffc50 With Sun Studio 12 on Solaris 10 ( AMD64 this time ) I get $ uname -a SunOS isis 5.10 Generic_137138-09 i86pc i386 i86pc $ cat /etc/release Solaris 10 5/08 s10x_u5wos_10 X86 Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms. Assembled 24 March 2008 $ /opt/studio/SOS12/SUNWspro/bin/cc -V cc: Sun C 5.9 SunOS_i386 Patch 124868-07 2008/10/07 usage: cc [ options] files. Use 'cc -flags' for details $ /opt/studio/SOS12/SUNWspro/bin/cc -o foo2 foo2.c $ ./foo2 8047d70 so .. pretty wildly different results. Dennis -- Dennis Clarke