Home > Enterprise >  Are temporaries created as arguments in a call guaranteed to hold their lifetimes until the function
Are temporaries created as arguments in a call guaranteed to hold their lifetimes until the function

Time:10-08

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.

[class.temporary]/4

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).

  • Related