Question with local variable

Why does the following code print "xxY"? Should local variables live within the whole function? Can I use this behavior, or will it be changed in a future C ++ standard?

I thought that according to the C ++ 3.3.2 standard, "The name declared in the block is local to this block. Its potential volume starts from the moment it is declared and ends at the end of its declarative area."

#include <iostream> using namespace std; class MyClass { public: MyClass( int ) { cout << "x" << endl; }; ~MyClass() { cout << "x" << endl; }; }; int main(int argc,char* argv[]) { MyClass (12345); // changing it to the following will change the behavior //MyClass m(12345); cout << "Y" << endl; return 0; } 



Based on the answers, I can assume that MyClass(12345); is an expression (and region). It makes sense. Therefore, I expect the following code to always print "xYx":

 MyClass (12345), cout << "Y" << endl; 

And it is allowed to make such a replacement:

 // this much strings with explicit scope { boost::scoped_lock lock(my_mutex); int x = some_func(); // should be protected in multi-threaded program } // mutex released here // // I can replace with the following one string: int x = boost::scoped_lock (my_mutex), some_func(); // still multi-thread safe // mutex released here 
+8
c ++ scope raii
Sep 07 '09 at 10:37
source share
4 answers

You have specified the standard correctly. We emphasize:

A name declared in a block is local to that block. Its potential volume starts from the moment of its announcement and ends at the end of its declarative region.

In fact, you did not declare the name . Line

 MyClass (12345); 

does not even contain ads ! What it contains is an expression that creates an instance of MyClass, evaluates the expression (however, in this particular case there is nothing to evaluate) and passes the result to void and destroys the objects created there.

Less confusing thing will sound like

 call_a_function(MyClass(12345)); 

You have seen this many times and know how it works, right?

+4
Sep 07 '09 at 10:50
source share

Object created in

 MyClass(12345); 

- This is a temporary object that is only alive in this expression ;

 MyClass m(12345); 

- an object that is alive for the entire block.

+16
Sep 07 '09 at 10:40
source share

In fact, you create an object without saving it in scope, so it is destroyed immediately after its creation. Therefore, the behavior you are experiencing.

You cannot access the created object, so why did the compiler save it?

+8
Sep 07 '09 at 10:39
source share

To answer other questions. The following is a comma operator call. It creates a temporary MyClass that includes a call to its constructor. Then it evaluates the second expression cout << "Y" << endl , which will print Y. Then, at the end of the full expression, it destroys the temporary one that its destructor will call. Therefore, your expectations were correct.

 MyClass (12345), cout << "Y" << endl; 

To do the following, you must add parentheses because the comma has a predefined value in the declarations. It will start declaring the some_func function, returning an int and not taking any parameters, and assigns a scoped_lock x object. Using parentheses, you say that all this is one expression of a comma operator.

 int x = (boost::scoped_lock (my_mutex), some_func()); // still multi-thread safe 

It should be noted that the following two lines are equivalent. The first does not create a temporary unnamed object using my_mutex as the constructor argument, but instead the parentheses around the name are redundant. Do not let the syntax confuse you.

 boost::scoped_lock(my_mutex); boost::scoped_lock my_mutex; 



I have seen the misuse of the terms scope and lifetime.

  • Scope is a place where you can refer to a name without specifying its name. Names have scopes, and objects inherit the scope of the name used to define them (thus, sometimes the standard says "local object"). The temporary object does not have scope because it did not receive a name. Similarly, an object created by new does not have scope. Scope is a compile-time property. This term is often used incorrectly in the standard; see this defect report , so it’s quite difficult to find the real meaning.

  • Lifetime is a runtime property. This means that the object is configured and ready to use. For an object of type class, the lifetime begins when the constructor completes execution, and ends when the destructor begins execution. Life time is often confused with volume, although these two things are completely different.

    The exact lifetime of the time series is determined. Most of them end their life after evaluating the full expression in which they are contained (for example, the comma operator above or the assignment expression). Time series can be associated with constant links that extend their lifespan. Objects thrown by exceptions are also temporary, and their lifespan ends when they no longer have a handler.

+5
Sep 07 '09 at 15:54
source share



All Articles