I have come across this discussion lately, where an array member of a returned struct is passed to another function directly and causes a crash.
Basically, we have a function returning an object of type struct S
(which contains an array), and call another function with the array element of that object:
#include <stdio.h>
#include <stdlib.h>
struct S
{
char array[10];
};
struct S func (void)
{
struct S s;
s.array[0] = 'H';
s.array[1] = 'e';
s.array[2] = 'l';
s.array[3] = 'l';
s.array[4] = 'o';
s.array[5] = '\0';
return s;
}
int main (int argc, char ** argv)
{
printf("%s\n", func().array);
return EXIT_SUCCESS;
}
While it was pointed out in the mentioned discussion that the problem lies in accessing the result of the call to func()
after the next sequence point, it is not clear to me why the following then works without crashing on my machine:
#include <stdio.h>
#include <stdlib.h>
struct S
{
char array[10];
};
struct S func (void)
{
struct S s;
s.array[0] = 'H';
s.array[1] = 'e';
s.array[2] = 'l';
s.array[3] = 'l';
s.array[4] = 'o';
s.array[5] = '\0';
return s;
}
int main (int argc, char ** argv)
{
printf("%s\n", &func().array[0]);
return EXIT_SUCCESS;
}
As opposed to the first example (which leads to the warning format '%s' expects argument of type 'char *', but argument 2 has type 'char[10]' [-Wformat=]
), the second example compiles without any issues - but anyway, the result of the call to func()
is accessed after the next sequence point, and therefore, according to the mentioned discussion, this should be undefined behaviour.
So I am wondering if either the second example running on my machine without crash is just luck, or if there is another point that comes into play here - maybe my understanding of why the first one crashes is just wrong, and what has been described in this answer of another related discussion is of more relevance here.
Edit (to clarify with respect to possible duplicate):
I am aware of this answer (1), and I also have read this answer (2) from a related discussion. However, I think both address different aspects corresponding to the topic I have opened: While (1) talks about undefined behaviour due to accessing the result of a function after the next sequence point, (2) talks about undefined behaviour due to having an array of value type (as opposed to lvalue type).
So, while it is obvious that example one is undefined behaviour, the main focus is on example two: As already mentioned, this runs without crashing on my machine. I am totally aware of this fact not being any evidence for the abscence of undefined behaviour - however, it is at least worth thinking about the abscence of undefined behaviour in that case. Furthermore, I do not see how the accepted answer in (1) would answer my question with respect to incorporation of points mentioned in (2) into this issue: It would be interesting to know if the fact that in my second example a pointer to char is used instead of an array type actually makes any difference with respect to the language rules.
Anyway, I assume that my second example also violates both constraints mentioned in (1) and in (2), but other opinions on this would be appreciated.