Home > front end >  What exactly are temporaries in C and in which specific cases the compiler will create them?
What exactly are temporaries in C and in which specific cases the compiler will create them?

Time:02-03

I am a C newbie and I am struggling on the temporaries topic. I don't find anywhere a clear list of all cases in which the compiler will create a temporary. Actually, a few days ago I had in mind that when we pass an rvalue as const reference parameter, then the compiler will create a temporary and will put the rvalue into that temporary to hold it, passing the temporary as the parameter. Giving this example to my teacher,

void func(const int& _param){}

int main()
{
  func(10);
  // int __tmp__ = 10;
  // func(__tmp__);
  return 0
}

he said in this case the compiler won't create a temporary, but instead will directly optimize the code replacing 10 in all the occurrences inside the function body, so after that, I am more confused than ever.

CodePudding user response:

If you are referring to the language concept rather than what the compiler ends up doing, a temporary in simple terms is a value that ends up arising from some expression and is not bound to any variable. Its value is usually used for some intermediate computation, and then discarded. Here is a somewhat contrived example.

std::string x = "foo";
std::string y = "bar";

auto length = (x   std::to_string(some_number)   y).size();
// __TEMP0__       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// __TEMP1__   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// __TEMP2__  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The result of std::to_string(some_number) is not assigned to anything as it is being used, so that alone is a temporary. It is used in the [sub]expression x std::to_string(some_number), which creates another temporary string, which itself is 'd with y, creating yet another temporary, whose size is taken and assigned to length. In this case all temporaries involve will exist0 until the end of the evaluation of the whole expression, and then discarded. It'll be as if the code were instead something like this.

std::string x = "foo";
std::string y = "bar";

std::string __TEMP0__ = std::to_string(some_number);
std::string __TEMP1__ = x   __TEMP0__;
std::string __TEMP2__ = __TEMP1__   y;

auto length = __TEMP2__.size();

Except that the temporaries remain as rvalues and will be destroyed after the evaluation of __TEMP2__.size().


0 Well, it'll be as if they existed. Who knows what your compiler will do to optimize it out.

CodePudding user response:

The "as-if" rule applies here. See https://en.cppreference.com/w/cpp/language/as_if.

Your job is to specify your intention by writing some C source code. The compiler's job is to turn that into machine code that matches the intention.

There's nothing in the C standard to tell you how many temporaries are created in your program. A good compiler will optimise your program to

int main(){}

If the creation of the temporary has an observable side-effect then the compiler's options are a little more restricted. But in NRVO and RVO circumstances it is allowed to ignore that. In later C standards it is required to.

CodePudding user response:

instead will directly optimize the code replacing 10 in all the occurrences inside the function body

It's up to the compiler whether or not (and how) to optimize this, or anything else. Except for certain exceptions (e.g. copy elision), optimizations are allowed if and only if they don't affect the observable behavior ("as-if rule" mentioned in the other answer).

when we pass an rvalue as const reference parameter, then the compiler will create a temporary and will put the rvalue into that temporary to hold it, passing the temporary as the parameter

Depends on the kind of rvalue. 10 is a prvalue, which are not even objects starting with C 17. References can't bind to prvalues directly, so it's materialized into an xvalue first, which is a temporary.

If you passed an xvalue, the reference would bind directly to it.

The above applies to C 17, I'm not sure how things worked before.

  •  Tags:  
  • Related