C++98 is not C99 :) there is no rvalue to lvalue conversion for rvalue arrays in C++98. Also this code is still undefined C99 but will most likely become valid C1x.

Sent from my iPhone

On Dec 16, 2008, at 8:45 AM, Jan Engelhardt <jeng...@medozas.de> wrote:


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

Reply via email to