Re: Returning a struct from a function - strange behavior



CBFalconer <cbfalconer@xxxxxxxxx> writes:
DiAvOl wrote:

#include <stdio.h>

typedef struct person {
char name[40];
int age;
} Person;

static Person make_person(void);

int main(void) {
printf("%s\n", make_person().name);
return 0;
}

static Person make_person(void) {
static Person p = { "alexander", 18 };
return p;
}

The above small program when compiled without the -std=c99 option
(using gcc 4.2.3) gives me a warning:
"warning: format ‘%s’ expects type ‘char *’, but argument 2 has
type ‘char[40]’"
and also fails with a segmentation fault when executed.

If I replace the line printf("%s\n", make_person().name); with
printf("%s\n", &make_person().name[0]); everything works as
expected.

Why does this happen? Isn't make_person().name a pointer to the
array's first element?

No. make_person() returns a struct by value, which has a field
identified by .name. That field is an array of 40 chars. It is a
portion of the return struct, which has never been put in
accessible memory.

Your alleged 'good' experience with lcc shows a bug in lcc. I
don't know if you mean lcc-win32 (which has quite a few known
insects) or lcc (which is less well known here).

What bug are you referring to? In another followup in this thread,
you said that the program's behavior is undefined; if so, anything
lcc-win does is permitted, and in this particular case its behavior
seems reasonable.

Larry Jones says that the stated behavior of lcc (or lcc-win) is what
was intended for C99. I'm skeptical that the C99 standard actually
states this, but N1336, the first draft for C1X, makes it explicit
that there is a temporary object. (It might arguably be a constraint
violation in C90, but lcc-win doesn't claim to support C90.)

--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
.



Relevant Pages