The following simple code segfaults under gcc 4.4.4
#include<stdio.h>
typedef struct Foo Foo;
struct Foo {
char f[25];
};
Foo foo(){
Foo f = {"Hello, World!"};
return f;
}
int main(){
printf("%s\n", foo().f);
}
Changing the final line to
Foo f = foo(); printf("%s\n", f.f);
Works fine. Both versions work when compiled with -std=c99. Am I simply invoking undefined behavior, or has something in the standard changed, which permits the code to work under C99? Why does is crash under C89?
I believe the behavior is undefined both in C89/C90 and in C99.
foo().fis an expression of array type, specificallychar[25]. C99 6.3.2.1p3 says:The problem in this particular case (an array that’s an element of a structure returned by a function) is that there is no “array object”. Function results are returned by value, so the result of calling
foo()is a value of typestruct Foo, andfoo().fis a value (not an lvalue) of typechar[25].This is, as far as I know, the only case in C (up to C99) where you can have a non-lvalue expression of array type. I’d say that the behavior of attempting to access it is undefined by omission, likely because the authors of the standard (understandably IMHO) didn’t think of this case. You’re likely to see different behaviors at different optimization settings.
The new 2011 C standard patches this corner case by inventing a new storage class. N1570 (the link is to a late pre-C11 draft) says in 6.2.4p8:
So the program’s behavior is well defined in C11. Until you’re able to get a C11-conforming compiler, though, your best bet is probably to store the result of the function in a local object (assuming your goal is working code rather than breaking compilers):