C ++ using snprintf in ostream with rvalue buffer, is it well formed?

I was wondering if I can use snprintf formatting in ostream so that I can embed the call in snprintf in the stream expression itself. This compiles in GCC 4.9, but is everything okay?

  cout << [](char (&&buf) [12], int d) { snprintf(buf, 12, "%d", d); return buf; } ({ }, 15) << endl; 
+6
source share
2 answers

It is well formed and well defined. {} used to copy-list-initialize the rvalue reference to char [12] , which creates a temporary char [12] array to which the link is bound. This is a temporary existence until the end of the full expression - in this case, to the semicolon, so the pointer to the element in the array can be safely returned and used for printing in this expression. (The lambda returns a char * pointing to the first element of this array.)

Standardese:

Β§8.5 [dcl.init] / p17:

The semantics of initializers is as follows. [...]

  • If the initializer is an (not enclosed in parentheses) bit-init-list, the object or link is initialized with the list (8.5.4).

Β§8.5.4 [dcl.init.list] / p3:

An initialization list of an object or link of type T defined as follows:

  • [...]
  • Otherwise, if T is a reference type, the temporary praleue of the type referenced by T is an initialized list of copies or direct-list-initialized, depending on the type of initialization for the link, and the link is bound to this temporary. [Note: As usual, the binding will fail and the program will be poorly formed if the reference type is an lvalue reference to a non-constant type. -end note]

Β§12.2 [class.temporary] / p5:

The temporary reference to the reference parameter in the function call (5.2.2) is stored until the completion of the full expression containing the call.

+7
source

I'm sure everything is in order. If I understand correctly, lambda will return an object of type char[12] as a temporary one (from automatically subtracting the return type). This temporary can then be passed to another function, in this case operator<<() .

This potentially means that copies are made, but RVO can take care of that.

UPDATE

As noted in the comments and in the best answer provided by TC, the return type received by this lambda is actually char *, not char [12]. I confirmed this with code in GCC.

+3
source

Source: https://habr.com/ru/post/978960/


All Articles