I need to return char arrays from a method what()
to be used in printf()
and variants.
The obvious solution of printing to a (thread local) static internal buffer obviously does not work because of the multiple calls problem.
#include <cstdio>
unsigned int counter = 1;
const char* what() {
static char buf[8];
buf[0] = counter % 10 '0';
buf[1] = '\0';
counter = 1;
return buf;
}
int main( int argc, char* argv[] ) {
printf( "%s %s\n", what(), what() );
}
Prints "2 2" instead of "1 2".
$ g test.cpp -o test
$ ./test
2 2
So I thought of creating a fixed size temporary buffer as in
template <std::size_t N>
struct TinyString {
char buf[N];
};
and implement the what()
routine in a way that it returns a TinyString
that will outlive the call.
unsigned counter = 1;
TinyString<4> what() {
TinyString<4> s;
s.buf[0] = counter % 10 '0';
s.buf[1] = '\0';
counter = 1;
return s;
}
The call is similar
int main() {
printf( "%s %s\n", what().buf, what().buf );
}
When I run this code it produces the right results 1 2
$ g test2.cpp -o test2
$ ./test2
1 2
Now the question is if the two temporaries are guaranteed by the C standard to outlive the printf()
call or it's UB in any way.
CodePudding user response:
Yes it's well-formed.
Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) that (lexically) contains the point where they were created.
That means the two temporaries will be destroyed after the invocation of printf
(immediately).