what is the scope of this variable in c++? - c++

If i define a function like this
std::string& returnstring(std::istringstream &ist)
{
std::string temp;
std::getline(ist,temp);
return temp;
}
and if i use this temp which is passed by reference to another function like this
void displaystring(std::string &temp)
{
std::cout<<temp;
}
would the string temp still be in scope when i pass it by reference to displaystring function?

The scope of a variable is the scope where it is declared. std::string temp; is declared within the body of the function returnstring, therefore that function body is the scope of the variable. It is an automatic variable, and therefore its lifetime ends at the end of its scope and it is automatically destroyed.
The returned reference will be invalid (i.e. it is a dangling reference). If you attempt to access the non-existing object through the invalid reference, then the behaviour of the program will be undefined.
To fix the function, a simple solution is to return a value instead.

Nope since the temp variable is local to the returnstring function and once the code is out of the retuernstring function the temp variable is no longer valid.
If at all you want to send the reference and get the answer then better option is to send the argument by reference as below,
void copyLineAsString(std::istringstream &ist, std::string& tempString)
{
std::getline(ist,tempString);
return;
}
I have few other suggestions to your code for the good coding practice,
Never use the '&' for the return type / return a variable by reference. Use camel casing or _ separator for the function names(Ex returnString or return_string).

No. The scope of temp is limited to the block where it is declared. Because you declared it on stack (you didn't use the keyword new), the variable temp will be destroyed the moment you exit the function.
The only way to keep the variable would be to have the value of temp be copied to a variable outside the function. For example, this would work:
std::string returnstring(std::istringstream &ist)
{
std::string temp;
std::getline(ist,temp);
return temp;
}
Because the return value is a copy rather than a reference, you could then do
std::string returned_string = returnstring(ist);
And have the value of temp be copied into a newly declared variable that could be used for your displaystring function.
In general, I would avoid declaring variables inside a function that you will need outside the scope of the function. Instead, return by value whenever you are returning variables built inside of the function (not recommended for large arrays and objects, however).

this is the reference variable which refers to the current class object which has called it. it has scope only inside the class and the same as the lifetime of the object which called it.

Related

What doees "this" keyword refer in this code block in c++?

const newString& newString::operator=(const newString& rightStr)
{
if(this!=&rightStr)
{
delete[] strPtr;
strLength=rightStr.strLength;
strPtr = newChar[strLength+1];
strcpy(strPtr,rightStr.strPtr);
}
return* this;
}
I know it avoids self copy, but what does "this" keyword refer to? I mean I thought it was rightStr but then why would it chechk if its equal to itself?
In a non-static class method, the this keyword is defined by the C++ language as a pointer to the object that the current class method was invoked on.
In your case, this refers to the newString object on the left side of the assignment statement that invoked newString::operator=. For example, in the below code:
newString strSrc, strDest;
strDest = strSrc;
Inside of newString::operator=, this is a pointer to the strDest object, and rightStr is a reference to the strSrc object.
"This" keyword can be used to pass current object as a parameter to another method or it can be used to refer current class instance variable.

How can we return a variable by reference while the scope has gone as

How can we return a variable by reference while the scope of the returning function has gone and its vars have been destroyed as soon as returning the var?
And if we make as the following to avoid that:
int fr = 9;
int& foo() {
//const int& k = 5;
return fr;
};
I will ask must we declare the returned var as a global var?
You can return a function local static variable instead of a global variable, of course:
int& foo() {
static int rc = 9;
return rc;
}
Note, however, that you still effectively have a global variable with all its problems, e.g., potentially concurrent access from multiple threads. At least, starting with C++11 the initialization of function local static variable is thread-safe: a function local static variable is initialized upon the first execution of the declaration statement.
Use the static keyword so that its scope remains throughout the code.
Example:-
int& fun(){
static int a =5;
return a;
}
int main()
{
int &b=fun();
cout<<b;
}
You can create a class and introduce a member, which you return as reference. This would be more transparent, than the 'static function member' solution, but requires more overhead, so that it is only reasonable, if you need a class anyway.
class Foo {
public:
Foo() ;
int& getFoo() {return myFoo;}
private:
int myFoo;
};
Note: OP and the other answers suggest variations on returning a pre-existing object (global, static in function, member variable). This answer, however, discusses returning a variable whose lifetime starts in the function, which I thought was the spirit of the question, i.e.:
how can we return a variable by reference while the scope of the returning function has gone and its vars have been destroyed as soon as returning the var.
The only way to return by reference a new object is by dynamically allocating it:
int& foo() {
return *(new int);
}
Then, later on:
delete &myref;
Now, of course, that is not the usual way of doing things, nor what people expect when they see a function that returns a reference. See all the caveats at Deleting a reference.
It could make some sense, though, if the object is one of those that "commits suicide" later by calling delete this. Again, this is not typical C++ either. More information about that at Is delete this allowed?.
Instead, when you want to return an object that is constructed inside a function, what you usually do is either:
Return by value (possibly taking advantage of copy elision).
Return a dynamically allocated object (either returning a raw pointer to it or a class wrapping it, e.g. a smart pointer).
But neither of these two approaches return the actual object by reference.
I'm assuming it's an academic example to examine a principle because the obvious way to code it would otherwise be to return by value.
With this precondition in mind this looks like a use case for smart pointers. You would wrap the variable in a smart pointer and return by value. This is similar to #Acorns answer but the variable will self delete once it is no longer being referred to, so no need for an explicit delete.

Pass by reference, child scope only?

I have tried searching on this, since I bet there are questions like these already. However I only get topics about passing by reference in a global setting.
I was wondering about the following;
Variable scope is in this function only and will be cleaned when leaving the scope
void Class::DoSomething(){
String s = "localVariable";
cout << s;
}
If I would change the prior function in the following two functions. Would the scope be also only in the parent function and will the variable memory be freed or do I have to call free()?
void Class::DoSomethingParent(){
String s = "localVariable"; //Local scope only
//This function uses the reference of my variable s.
Class::DoSomethingChild(s);
//Does the prior function do anything special because of the reference,
//so I have to call free(s)?
//Or does the variable still gets freed after leaving the scope of this function?
}
void Class::DoSomethingChild(String& value){
cout << value;
}
Objects with an Automatic Storage Duration in C++ are essentially objects declared within a function block scope, that scope owns and controls the lifetime of such objects created therein. Example:
void function(){
....
String s = "Some Data";
someFuncByReference(s);
....
} //All objects of automatic storage duration owned by this scope are destroyed here...
Irrespective of whether you pass the object by reference or take the address of the object, and pass unto a function. The called function, someFuncByReference still doesn't control the lifetime of s, and should not destruct s1.
This applies to any "function", including, non member-functions, member-functions and function specializations produced by templates. Note that, this is not the same with data members of a class. The lifetimes of class data members are controlled by the constructor and destructor of that class.
1: However, if it does, it must create another one using placement-new.

Pointer to local variable is stored outside the scope of this variable

For the following code snippet, which is a part of libgearman
gearman_job_st *gearman_worker_grab_job(gearman_worker_st *worker_shell,
gearman_job_st *job,
gearman_return_t *ret_ptr)
{
if (worker_shell and worker_shell->impl())
{
...
gearman_return_t unused;
if (ret_ptr == NULL)
{
ret_ptr= &unused;
}
...
}
assert(*ret_ptr != GEARMAN_MAX_RETURN);
return NULL;
}
PVS-Studio reported:
Viva64-EM
full
671
/nfs/home/xxx/src/gearmand/libgearman/worker.cc
error
V506
Pointer to local variable 'unused' is stored outside the scope of this variable. Such a pointer will become invalid.
false
2
{
ret_ptr= &unused;
}
------------
Regarding the question Pointer to local variable outside the scope of its declaration, if I understand that correctly, malloc and free should be used for refactoring. My question is if there is an other appropriate refactoring alternative. For instance using of std::unique_ptr:
ret_ptr = std::make_unique<gearman_return_t>();
The ret_ptr parameter to the function in question is expected to point to a variable in the calling function. This pointer is then dereferenced for both reading and writing this external variable.
The if (ret_ptr == NULL) block checks whether the caller actually passed in the address of some variable. If not, this pointer is then made to point to the local variable unused so that the pointer can still be safely dereferenced later in the code. But since ret_ptr now points to a local, changes made by dereferencing it are not seen outside the function. This is fine, since the caller passed in NULL for ret_ptr. Similarly, since ret_ptr is a parameter, any changes to it are not visible outside of the function.
Nothing needs to be refactored here. The code works as intended with regard to ret_ptr. This is a false positive from PVS-Studio.
EDIT:
This is NOT a false positive. The unused variable is defined at a lower scope than ret_ptr, namely the scope of the first if block in the function. After the if block, ret_ptr is then dereferenced. If it was pointing to ununsed, that variable is now out of scope and dereferencing ret_ptr invokes undefined behavior.
To fix this, unused must be declared and assigned to above the if block:
gearman_job_st *gearman_worker_grab_job(gearman_worker_st *worker_shell,
gearman_job_st *job,
gearman_return_t *ret_ptr)
{
gearman_return_t unused;
if (ret_ptr == NULL)
{
ret_ptr= &unused;
}
if (worker_shell and worker_shell->impl())
{
...
}
assert(*ret_ptr != GEARMAN_MAX_RETURN);
return NULL;
}

Is 'this' a local variable?

Here I am taking an example of overloading the increment operator:
class Digit
{
int m_digit;
public:
Digit (int value) //constructor
{
m_digit = value;
}
Digit& operator++();
int ret_dig (){return m_digit;}
};
Digit& Digit::operator++()
{
if (m_digit == 9)
m_digit = 0;
else ++m_digit;
return *this;
}
int main ()
{
Digit my_dig (5);
++my_dig;
return 0;
}
I have been told that local variables can't be returned. Isn't "this" a local variable? Here is what I think:
A pointer of type Digit is attached to the member function (overloaded operator function). When compiler sees the line ++my_dig, that is an instance of Digit class, it calls the member function. The address of the instance my_dig is passed as argument to the function and there is a hidden "const Digit*" named "this" to catch the argument. "this" is dereferenced(implicitly) to access m_digit, that is a member variable of class Digit. All the increment or wrapping is done inside the function and a reference to dereferenced "this" is then returned to the caller. Yes, this is the point to my confusion. If "this" is a local variable of type const Digit*, shouldn't it contain garbage when returned because "this" is going out of scope where the block ends haaa?
this is an implicit parameter to all member functions which points to the object itself -- which has a strictly longer lifetime than the method. The parameter itself is a local variable, but the object that it points to exists outside the method.
In this case the object is created on the first line of your main function and then lives until the main method exits. Thus the object is safely alive throughout the call to operator++!
The *this is the object and not a local variable. Any temporary objects which the compiler deems necessary to allocate, such as those needed to complete a expression, has a lifetime to the end of the expression.
This becomes interesting for objects which has a destrctor, as the destructor run not when the individual parts of the expression is completed, but when the entire expression completes -- hence your *this variable will survive just sufficiently long to complete what is needed.
Have a look at this question for deeper discussion
this is a local variable, but it is initialized by &my_dig when it enters the method. The value of &my_dig has the same lifetime as my_dig, which ends at the end of the main block. So while this goes out of scope, the value of this is still valid.