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.
Related
Say I have a function that I want to call multiple times. At the start of this function I have declared an integer for a value of zero, and at the end of it I increased its value by one. Now I want to save the new value so when I call the function again the value of that variable becomes 2. Is there a way to do that besides getting the variable from another function or declare it at the top of line codes out of the functions?
TLDR
Yes, using the static keyword.
It changes the lifetime of the object declared with it, that becomes available for the whole duration of the program.
That said, you should be careful with using static local variables, because you're adding a state to the function execution.
#include <iostream>
using namespace std;
void printX()
{
static int x;
cout << "x: " << x << endl;
++x;
}
int main()
{
for (int i = 0; i < 10; ++i)
printX();
}
https://www.jdoodle.com/iembed/v0/909
There's more to the static keyword and you should look into it.
I'd suggest you read at least a couple of articles about it:
https://en.wikipedia.org/wiki/Static_(keyword)#Common_C
https://www.geeksforgeeks.org/static-variables-in-c/
you can use a static variable declared inside the function, since it is static the initialization to zero will happen only once and the rest of the time you call the function it will retain its value...
here is an example:
#include <iostream>
void foo(int x)
{
static int counter{0};
std::cout<< "this is x: " << x << std::endl;
counter++;
std::cout<< "this is counter: " << counter << std::endl;
}
int main() {
foo(1);
foo(10);
std::cout<< "something else in the app is executed... " << std::endl;
foo(101);
return 0;
}
and here the output:
this is x: 1
this is counter: 1
this is x: 10
this is counter: 2
something else in the app is executed...
this is x: 101
this is counter: 3
template <typename T>
T sum(stack<T>& s){
if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = sum(s)+first;
s.push(first);
return total;
}
}
The code above is designed to recursively sum the elements of any given stack of type T with the only condition being that the integrity of the stack must be restored at the end of the function. Meaning, I am allowed to make changes to the stack to sum the elements as long as it is in the same state as it was before it was passed when the function terminates.
As you will observe the given code works however I do not understand the control flow or execution sequence of the recursive calls and return statements. When I see this code I understand how the elements are summed, however I do not understand how the call to "s.push(first)" adds all of the elements back on to the stack. I'm having a hard time wrapping my head around why it wouldn't solely push the last element of the stack and then return the total.
My current understanding of why this works is incomplete and likely flawed and is as follows: because each return statement returns to the most recent caller, when the recursion hits the base case and terminates, the return statements will work their way back up the recursive call stack until it gets to the original caller and therefore executing "s.push()" at each movement back up the stack.
What is causing confusion for me is the execution sequence once the stack is empty and I think it is due to a lack of understanding the way the function recurses back up the call stack. If someone could lay out the execution sequence and explain the way recursion works with operations underneath the recursive call that would me much appreciated.
Thanks!
Your overall understanding is correct. You're only missing connecting the final dots.
The key point to remember is when a function returns, it returns to wherever it was called from. Recursive functions are no different in that fundamental respect. Recursive function calls work exactly the same way.
It will help to understand if you label each recursive call. Let's call the initial invocation of the recursive function "A". When the recursive function calls itself, recursively, call that invocation of the recursive function "B". Then it calls again, and that's "C". Followed by "D", and so on.
The key point to understand is that when a function returns, it returns to wherever it was called from. So, "D" returns to "C", which returns to "B", and it returns to "A".
Now look at your recursive function. When the stack had one value left, let's call it "D", it removes the "D" value from the stack and makes the recursive call "E", which discovers that the stack is empty.
So it returns to "D", which pushes the "D" value back to the stack, which now has one value again. Then it returns to "C", which pushes the "C" value back to the stack, which now has the two original, last, values on the stack, in the same order.
In this fashion, the function calls unwind in reverse order from their original calling sequence, restoring the stack to exactly what it was, originally.
Your function looks something like this:
if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = sum(s)+first;
s.push(first);
return total;
}
To kind of see how this works, let's pretend that this is actually a macro, and expand the function into what would generally get executed:
if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = sum(s)+first;
s.push(first);
return total;
}+first;
s.push(first);
return total;
}
This is of course, just an example. Since it is not a macro,this isn't what really happens. It is just to illustrate.
However, the point is that the code in your function will get executed every time you call the function similarly to the second code snippet. Thus, what ends up happening is that the innermost function pushes to the stack, and then the calling function pushes to the stack, etc.. until everything gets pushed back on to the stack. So, even though there is one call to push on the stack, it will still get executed every time the function executes.
"If someone could lay out the execution sequence ... "
It is always allowed to add (removable) cout's to the executing code. The following illustrates one approach.
Note 1: To simplify, I removed template issues. The demo uses int.
Note 2: dumpStack is not recursive.
Note 3: m_stck is data attribute of the class, so it need not be passed from sumStack to sumStack.
#include <iostream>
using std::cout, std::endl; // c++17
#include <iomanip>
using std::setw, std::setfill;
#include <string>
using std::string, std::to_string;
#include <stack>
using std::stack;
#ifndef DTB_PCKLRT_HH
#include "../../bag/src/dtb_pclkrt.hh"
using DTB::PClk_t;
#endif
class StackW_t // stack wrapper UDT (user defined type)
{
private:
int m_N; // max elements
stack<int> m_stck; // default ctor creates an empty stack
public:
StackW_t(int N = 10) // simple default size
{
m_N = N; // capture
assert(m_N > 1); // check value
for (int i=0; i<m_N; ++i)
m_stck.push(N - i); // simple fill
}
~StackW_t() = default; // dtor default deletes each element of m_stck
// recurse level-vvvv
int sumStack(int rLvl = 1)
{
if (m_stck.empty())
{
cout << "\n" << setw(2*rLvl) << " " << setw(4) << "<empty>";
return 0;
}
else
{
int first = m_stck.top(); // top element
m_stck.pop(); // remove top element
cout << "\n" << setw(2*rLvl)
<< " " << setw(4) << first; // recurse report
// use first value then recurse into smaller stack with next rLvl
int sum = first + sumStack(rLvl+1);
cout << "\n" << setw(2*rLvl) // decurse report
<< " " << setw(3) << "(" << first << ")";
m_stck.push(first); // restore element after use
return sum;
}
}
void dumpStack(string lbl, int rLvl = 1)
{
stack<int> l_stck = m_stck; // for simplicity, use copy of
cout << "\n dumpStack " << lbl << setw(2*rLvl);
while (!l_stck.empty())
{
cout << " " << " " << l_stck.top();
l_stck.pop(); // remove displayed member
}
cout << "\n";
}
}; // class StackW_t
// Functor 829
class F829_t // use compiler provided defaults for ctor and dtor
{
PClk_t pclk; // posix clock access
public:
int operator()(int argc, char* argv[]) { return exec(argc, argv); }
private:
int exec(int , char** )
{
int retVal = 0;
// create, auto fill with value 1..10
StackW_t stk;
stk.dumpStack("before"); // invoke display
cout << "\n stk.sumStack(): ";
uint64_t start_us = pclk.us();
// invoke recursive compute, start at default rLvl 1
int sum = stk.sumStack();
auto duration_us = pclk.us() - start_us;
cout << "\n sum: " << sum << endl;
stk.dumpStack("after"); // invoke display
cout << "\n F829_t::exec() duration "
<< duration_us << " us (" << __cplusplus << ")" << std::endl;
return retVal;
}
}; // class F829_t
int main(int argc, char* argv[]) { return F829_t()(argc, argv); }
Note 4: during recurse, rLvl increases, so the value shifts to the right for each line
Note 5: during decurse, rLvl is restored upon function return, thus output is also restored to alignment
Note 6: before and after of stack shows successful restore of stack
Output:
dumpStack before 1 2 3 4 5 6 7 8 9 10
stk.sumStack():
1
2
3
4
5
6
7
8
9
10
<empty>
(10)
(9)
(8)
(7)
(6)
(5)
(4)
(3)
(2)
(1)
sum: 55
dumpStack after 1 2 3 4 5 6 7 8 9 10
So when I have this function, and I print it to the console via multiple statements, I get the expected results:
0
1
But when I print the function out through just one cout statement on the same line, I get:
3 2
(This is after the initial 0 and 1 that were previously printed)
Why does it print backwards?
#include "stdafx.h"
#include <iostream>
using namespace std;
int addOne()
{
static int s_num = -1;
return ++s_num;
}
int main()
{
cout << addOne() << "\n";
cout << addOne() << "\n";
cout << addOne() << " " << addOne() << "\n";
return 0;
}
You are actually stumbling on unspecified behavior. In this context, and any other such context where the operators are of the same precedence, the function calls can be evaluated in any order. In this case, the compiler chose to evaluate the second function call before the first, but other compilers might do it differently.
The arrays are passed by reference. Any changes made to the array within the function changeArray will be observed in the calling scope (main function here).
However the codes below print 0 1 in the 1st cout, and print 2 in the 2nd "cout". What I don't understand is that why the first cout prints the original value of array[0]=1 instead of the changed value of array[0]=2?
Thanks a lot.
#include <iostream>
using namespace std;
int changeArray(int array[]) {
array[0]=2*array[0];
return 0;
}
int main() {
int array[]={1,2,3,4};
cout << changeArray(array) << " " << array[0] << endl;
cout << array[0] << endl;
return 0;
}
To make sure that the compiler doesn't reorder the execution:
cout << array[0] << endl;
changeArray(array);
cout << array[0] << endl;
This prints 1 and then 2.
The C++ compiler is allowed to optimize the code by reordering the execution of code within a single expression (e.g. cout << changeArray(array) << " " << array[0] << endl). To avoid that, and to make sure changeArray gets called first, you need to split your expression to separate statements, e.g. by using the semicolon (;). Everything before the semicolon gets executed before anything after the semicolon can start.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
I'm having trouble understanding the order of actions when overloading the postfix operator. Let's examine the two small examples below:
int i = 0;
std::cout << std::endl << "i: " << i;
i = ++i;
std::cout << std::endl << "i: " << i;
i = i++;
std::cout << std::endl << "i: " << i;
MyClass myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = ++myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = myObject++;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
Two very different behaviors emerge. The output is as follows:
i: 0
i: 1
i: 2
myObject: 0
myObject: 1
myObject: 1
Different behavior, you see. Here's the outline of my overloaded-operator methods.
MyClass & MyClass::operator++ ()
{
++myValue;
return *this;
}
MyClass MyClass::operator++ (int postfixFlag)
{
MyClass myTemp(*this);
++myValue;
return myTemp;
}
Alright. Prefix makes sense. You increment whatever you need to, then return the same object, now modified, in case of assignment. But postfix is what's tripping me up. It's supposed to assign, then increment. Here we're self assigning. So with the built-in integer type, it makes sense. I assign i's value to itself, then i gets incremented. Fair enough. But let's say MyClass is a recreation of the int. It starts out at 0, gets prefix-incremented, and becomes 1. Then, the key line. myObject = myObject++. That's the same thing as myObject = myObject.operator++(int postfixFlag). It gets called. myTemp gets initialized with the value 1. It's incremented to 2. Then we return the temp. That works, if we're assigning to another object. But here I'm self-assigning, so after the increment to 2, myObject is set equal to the returned temp object initialized with the initial value, and we're back to 1! That makes sense. But it's a fundamentally different behavior.
How do I work around it? How does int do it? How is this method generally written? Do you have any comments about C++ behavior and design relating to this? Etc. I'm a little perplexed right now, since books and online examples always seem to use a variant on the method above.
Thanks for reading, and any input will be appreciated!
As others have said, with int the behaviour is undefined. But I thought I'd try to explain why for your MyClass it is not ever getting to 2.
The trick is that you are taking the following three steps in the postfix version:
Making a copy of this called myTemp (with myValue == 1).
Incrementing this->myValue (so myTemp.myValue == 1; this->myValue == 2).
Returning myTemp (with myValue == 1).
So you are modifying this, but the code that calls myObject++ is never going to see this again. It's only going to look at the value returned, which is a copy of the old myObject.
The code for operator++ is fine. The problem is how you are using it -- you shouldn't be writing the result of a pre-increment or post-increment back to the same variable (behaviour is undefined). Here is some code that might be more instructive:
int i = 0;
std::cout << "i: " << i << std::endl;
int j = ++i;
std::cout << "i: " << i << ", j: " << j << std::endl;
int k = i++;
std::cout << "i: " << i << ", k: " << k << std::endl;
MyClass myObject;
std::cout << "myObject: " << myObject.getMyValue() << std::endl;
MyClass myObject1 = ++myObject;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject1: " << myObject1.getMyValue() << std::endl;
MyClass myObject2 = myObject++;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject2: " << myObject2.getMyValue() << std::endl;
This prints:
i: 0
i: 1, j: 1
i: 2, k: 1
myObject: 0
myObject: 1, myObject1: 1
myObject: 2, myObject2: 1
I changed your code so that rather than assigning back to itself, it assigns to a fresh variable each time. Note that in both the int and the MyClass cases, the main variable (i/myObject) is incremented both times. However, in the pre-increment case, the fresh variable (j/myObject1) takes on the new value, while in the post-increment case, the fresh variable (k/myObject2) takes on the old value.
Edit: Just answering another part of the question, "How does int do it?" I assume this question means "what does the pre-increment and post-increment code look like in the int class, and how can I make mine the same?" The answer is, there is no "int class". int is a special built-in type in C++ and the compiler treats it specially. These types aren't defined with ordinary C++ code, they are hard-coded into the compiler.
Note: For anyone who wants to try this themselves, here is the code for MyClass that the question didn't include:
class MyClass
{
private:
int myValue;
public:
MyClass() : myValue(0) {}
int getMyValue() { return myValue; }
MyClass& operator++();
MyClass operator++(int postfixFlag);
};