I’m having trouble printing a member of a struct that is returned from a function:
#include <stdio.h>
struct hex_string
{
char a[9];
};
struct hex_string to_hex_string_(unsigned x)
{
static const char hex_digits[] = "0123456789ABCDEF";
struct hex_string result;
char * p = result.a;
int i;
for (i = 28; i >= 0; i -= 4)
{
*p++ = hex_digits[(x >> i) & 15];
}
*p = 0;
printf("%s\n", result.a); /* works */
return result;
}
void test_hex(void)
{
printf("%s\n", to_hex_string_(12345).a); /* crashes */
}
The printf call inside to_hex_string_ prints the correct result, but the printf call inside test_hex crashes my program. Why exactly is that? Is it a lifetime issue, or is it something else?
When I replace the printf call with puts(to_hex_string_(12345).a), I get a compiler error:
invalid use of non-lvalue array
What’s going on here?
There is a rule in C which seldom comes into effect, which states:
In this case, there is a sequence point after the arguments to
printf()are evaluated and before theprintf()function itself executes. The pointer you pass toprintf()is a pointer to an element of the return value itself – and whenprintf()tries to access the string through that pointer, you get your crash.This issue is hard to run into, because a function value isn’t an lvalue so you can’t directly take a pointer to it with
&.