>
> 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