I saw the following program on a site and I cannot understand the output .
http://codepad.org/T0qblfYg
#include <iostream>
using namespace std;
int i;
class A
{
public:
~A()
{
i=10;
}
};
int foo()
{
i=3;
A ob;
return i;
}
int main()
{
cout <<"\n 1) Before calling i is "<<i;
cout <<"\n 2) i = "<<i << " & the function return value = "
<< foo() << " and now i is " << i << endl;
return 0;
}
output is :
1) Before calling i is 0
2) i = 10 & the function return value = 3 and now i is 10
Now i is a global variable and destruction of A should have changed it to 10 before the call was returned to main. It is suggested that destruction of A happens after the call is returned to main but as a caller when i call a function i always expect the result to be final . Here the function return value is not 10 but 3 .
My question is why did i see this and where exactly is destruction getting called .
The order of evaluation is not what you would expect. When calling functions, the arguments to the functions can be evaluated in any order and even interleaved. So if you call
f( g(), h(), i() );
the order in which g(), h() and i() are called is up to the compiler. This also applies to operators. When you have an expression of the form
expr1 << expr2 << expr3 << expr4;
the order in which the expressions are evaluated is arbitrary. You only know, that the operator<< calls will be evaluated from left to right, because the operator is left-to right associative and you could rewrite the expression as
((expr1 << expr2) << expr3) << expr4;
The syntax tree looks like that:
<<
/ \
<< expr4
/ \
<< expr3
/ \
expr1 expr2
The leafs of the syntax tree can be evaluated in any order, even interleaved. And after all the leafs of an operator or function call are evaluated, the function itself will be called.
In your case foo() seems to get called before i gets printed out the first time and it is perfectly valid (though unexpected) behaviour.
Destructors run after the expression in the return statement is evaluated. If it was the other way around you'd be in deep trouble:
std::string f() {
std::string res = "abcd";
return res;
}
This function should return a string object that holds "abcd", not a copy of a string object that has already been destroyed.
why did i see this and where exactly is destruction getting called .
I believe the instance destructor is called when that instance goes out of scope. You might test it the following way (by controlling the scope of the instance -- see bar() below)
Note - to reduce confusion, I 1) renamed the global and 2) explicitly controlled when the foo or bar is called w.r.t. subsequent cout.
int g; // uninitialized!
class A
{
public:
~A()
{
g=10;
}
};
int foo()
{
g=3;
A ob;
return g;
} // <<<<<<<<<<< ob destructor called here
int bar()
{
g=3;
{
A ob;
} // <<<<<<<<<<< ob destructor called here
return g;
}
int t272(void)
{
g = 0; // force to 0
std::cout << "\n 1) Before calling foo g is " << g;
int fooRetVal = foo(); // control when called
// do not leave up to compiler
std::cout << "\n 2) after foo, g = " << g
<< "\n 3) fooRetVal = " << fooRetVal
<< "\n 4) and now g = " << g
<< std::endl;
g = 0; // force to 0
std::cout << "\n 1) Before calling bar g is " << g;
int barRetVal = bar(); // control when called
// do not leave up to compiler
std::cout << "\n 2) after bar, g = " << g
<< "\n 3) barRetVal = " << barRetVal
<< "\n 4) and now g = " << g
<< std::endl;
return (0);
}
With the output
1) Before calling foo g is 0
2) after foo, g = 10
3) fooRetVal = 3 <<< dtor called after return of foo
4) and now g = 10
1) Before calling bar g is 0
2) after bar, g = 10
3) barRetVal = 10 <<< dtor was called before return of bar
4) and now g = 10
Related
#include <iostream>
using namespace std;
class foo
{
private:
static int cnt; // number in memory
static int nextid; // the next id number
public:
int id; // not shared - each object has it's own
foo()
{
cnt++; // update the counter of alive foos
id = nextid++; // assign an id
cout << "foo # " << id << " is alive " << endl;
}
~foo()
{
cnt--;
cout << "foo # " << id << " is dead " << endl;
}
void stats()
{
cout << "I am foo number " << id << endl;
gstats();
}
static void gstats()
{
cout << "Objects currently alive: " << cnt << endl;
cout << "Total number ever created: " << nextid << endl;
}
foo( foo &f)
{
cnt++; // update the counter of alive foos
id = nextid++; // assign an id
cout << "foo # " << id << " is alive and copied from " << f.id << endl;
}
};
int foo::cnt = 0;
int foo::nextid = 0;
void dmy1( foo a )
{
cout << "called dmy1 ( by value) id is " << a.id << endl;
}
void dmy2( foo &a)
{
cout << "called dmy2 (by reference) id is " << a.id << endl;
}
int main(void)
{
foo::gstats();
foo f1, f2;
f1.stats();
dmy1(f2);
foo::gstats();
}
This is the code my professor gave me to practice C++ static code.
But when I run this program, I have a question.
Objects currently alive: 0
Total number ever created: 0
foo # 0 is alive
foo # 1 is alive
I am foo number 0
Objects currently alive: 2
Total number ever created: 2
foo # 2 is alive and copied from 1
called dmy1 ( by value) id is 2
foo # 2 is dead
Objects currently alive: 2
Total number ever created: 3
foo # 1 is dead
foo # 0 is dead
This is the output.
But I don't know the reason why this function is called
Could you explain?
foo( foo &f)
{
cnt++; // update the counter of alive foos
id = nextid++; // assign an id
cout << "foo # " << id << " is alive and copied from " << f.id << endl;
}
And, also, Why static void gstats(){ ~ } is called after destructing foo #2 ?
Ok, i try to explain what happens
First it is showed no objects exist at this point
foo::gstats();
Now f1 and f2 are declared and created on stack (2 objects alive)
foo f1, f2;
f1.stats is called and shows the current state
f1.stats();
f2 is passed by value (copyed on stack with copy constructor call foo( foo &f)) to dmy1 (3 objects alive)
dmy1(f2);
after leaving dmy1 it's scope (stack variables used by it) is destroyed and f2's copy gets it's destructor called (2 objects alive) and this status is displayed
foo::gstats();
Then main() is left and it's scope is destroyed as well and f1 and f2's destructors are called (0 objects alive)
The function is called copy constructor. It's called because you pass the object f2 to dmy1 by value and a copy of the object is constructed. If you would change the object a inside dmy1, f2 would stay the same - because you implicitly constructed a copy when you passed the parameter in by value.
foo#2 is destructed when you exit the function dmy1, because it's only alive inside that function. So it's destructed before calling gstats.
It is copy constructor, as it was said. But copy constructor should have been declared like this:
foo(const foo &f)
{
...
}
I am trying to understand how lambdas work in C++ in depth. I have written the following piece of code.
#include <iostream>
#include <functional>
struct A
{
A() { std::cout << "A" << (data = ++count) << ' '; }
A(const A& a) { std::cout << "cA" << (data = a.data + 20) << ' '; }
A(A&& a) { std::cout << "mA" << (data = std::move(a.data) + 10) << ' '; }
~A() { std::cout << "dA" << data << ' '; }
int data;
static int count;
};
int A::count = 0;
void f(A& a, std::function<void(A)> f)
{
std::cout << "( ";
f(a);
std::cout << ") ";
}
int main()
{
A temp, x;
auto fun = [=](A a) {std::cout << a.data << '|' << x.data << ' ';};
std::cout << "| ";
f(temp, fun);
std::cout << "| ";
}
The output is below.
A1 A2 cA22 | cA42 mA52 dA42 ( cA21 mA31 31|52 dA31 dA21 ) dA52 | dA22 dA2 dA1
This is quite clear to me, except for the 'mA52' move constructor call. Note that I am using variable capture by value, so without the move constructor, the copy-constructor would be called here. Why is there an additional copy/move at this step? One would expect the object to be copied only once when fun is passed by value as an argument to f. Furthermore, the first copy of the object is immediately destroyed. Why? What is this intermediary copy?
Let's call your lambda type L. It's unnamed, but it gets confusing to refer to it without a name.
The constructor std::function<void(A)>(L l) takes L by value. This involves creating a copy of the original fun.
The constructor then moves the lambda from l into some storage managed by the std::function<void(A)> wrapper. That move also involves moving any captured entities.
std::function<void(A)> takes the function object you pass to it by value (this is the cA42 in your output). It then moves the function object in to its internal storage (this is the mA52).
Below is a output question.I am not able to understand why its answer is 30.
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
static int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
OUTPUT:30
Can anybody tell why output is coming to be 30 and also can explain the role of static keyword
In computer programming, a static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program
void foo()
{
int a = 10;
static int b = 10;
a++;
b++;
std::cout << "a : " << a << " , b : " << b << std::endl;
}
A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable.
int a = 4;
int b = a;
int &c = a;
c++;
std::cout << "b = " << b << std::endl; //4
std::cout << "a = " << a << std::endl; //5
std::cout << "c = " << c << std::endl; //5
/* Becaues c is a refence to a, it means that
a and c are just different names to the same memory location
so updating either one updates the actual value in memory
*/
a++;
std::cout << "c = " << c << std::endl; //6
std::cout << "a = " << a << std::endl; //6
//consider the function below:
int &bar()
{
static int a = 5;
std::cout << "a is " << a << std::endl;
return a;
}
Testing the two:
int main()
{
for (int i = 0; i < 3; i++)
foo();
//for every call of foo():
//memory allocation for a is created and deleted when a goes out of scope
//memoery allocation for b extends through out the life of the program
//bar() returns a reference to "a" i.e
int reference_to_a = bar(); //prints 5
reference_to_a = 30;
bar(); //prints 30
bar() = 50; //prints 30 and later assigns 50 to the reference returned.
bar(); //prints 50
}
static make the variable persist across function calls.
which means static int x = 10; will be executed once when func is called for the first time.
int static_test()
{
static int x = 10;
x++;
return x;
}
static_test(); // first call will return 11
static_test(); // second call will return 12 because the value of x ( was saved and was then incremented)
static_test(); // third call will return 13
Now, you need to understand what reference are. To understand what reference are you need to understand pointers. I am guessing you will easily find some website explaining those two.
case 1:
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
Here, in the call fun(), we are declaring a local variable int x, which goes out of scope once it returns from fun().
so, in the line cout << fun() a new variable is declared and address of the new variable is returned.
case 2:
static int x = 10;
here, since variable 'x' is static, it can be initialized only once. i.e., the first time x is initialized to 5 and then over written to 30.
now when you are making the function call subsequent times, static int x = 5 is ignored. Hence, it returns the value 30
I have this following code that I must follow:
#include <iostream>
using namespace std;
class T {
public:
T() {}
};
class S {
public:
static int i;
S() { i++; }
S(int unused) { i += 2; }
S(T unused) { i += 3; }
};
int S::i = 0;
S f(S unused)
{
return 0;
}
S g(S& unused)
{
return 1;
}
int main()
{
cout << S::i << "\n";
S s1, s2(2);
cout << S::i << "\n";
T t;
cout << S::i << "\n";
S s3(t);
cout << S::i << "\n";
f(t);
cout << S::i << "\n";
g(s1);
cout << S::i << "\n";
}
From following every declaration and instantiation in the main method, I can follow the output as follows:
0
3
3
6
6
6
I am correct until:
0
3
3
6
But the last two numbers that will be outputted are:
11
13
I am unsure what exactly f(t) and g(s1) do? I am unable to follow how they are changing the value of i.
What do these two statements do?
Both f() and g() are declared to return a value of type S but they actually do a return with an integer value.
So what actually happens is that a temporary value of type S is automatically created from the integer using the conversion constructor S(int unused). That function increments S::i by 2.
Also f() takes as argument a value of type S, but it is calld with a value of type T. Hence, a temporary value of type S is automatically created by the compiler, using the conversion constructor S(T unused). That function increments S::i by 3.
In the program below I call a function foo() which sets a global variable i
and then calls the constructor of class A, where i should also be set, but
to 10. However the output of my program is 3 0, can you please explain?
#include <iostream>
int i;
class A
{
public:
~A()
{
i=10;
}
};
int foo()
{
i = 3;
A ob;
return i;
}
int main()
{
std::cout << "i = " << foo() << " " << i << "\n";
}
There are two important points to consider here:
The order of evaluation of arguments to a function is Unspecified. So either:
foo() gets executed first or
i gets printed first
It is specific to your compiler. Looks like your compiler evaluates argument from right to left, hence the global i which is 0 gets evaluated as 0. Remember that this order may be different for other compilers and you should not rely on behavior of one implementation.
As for why 3? The destructor for ob gets called after the function returns. So i gets set to 10 after the return, what gets returned is a copy and that copy has a value 3.
Its because return value gets copied after destructor.
I gets printed first and foo gets called later so the output 3 0.
If you print like below
cout << "i = " << i <<" " << foo()<< endl;
you will see 10 3 as output.
At the moment you are passing the 'i' as the argument, it's value is zero. The foo() will change the value in the destructor to 10 AFTER that.
As juanchopanza suggested, add another line std::cout << i; and you will see what you expect, because at that point the value is 10.
Print the foo() and i by using two cout statements as follows,
cout << "i of foo = " << foo();
cout <<"\ni in main = " << i << endl;
The output will be
i of foo = 3
i in main = 10
Earlier you were getting 3 0 as output because the overloaded operator << was being evaluated from left to right by your compiler.