local variables of static member functions - c++

Today we came accross a problem concerning static member functions in an multithreaded environment. The question we asked ourselves and couldn't find a satisfying answer is:
are local varialbes of static member functions static as well?
// header
class A
{
static int test();
}
// implementation
int A::test()
{
int a = rand();
int b = rand();
int c = a + b;
return c;
}
Say you have two threads both calling A::test(). Is it possible that while thread 1 proccesses c = a + b thread 2 enters test() and changes the value of a by assigning the new return value of rand() or in other words do both threads operate an the some memory locations for a, b and c?

No. The stack frames are independent for each thread's invocation of the function, and each gets its own locals. (You do need to be careful if you're accessing actual shared data e.g. static members in the class.)

Unless explicitly declared as static, no they're not. They're on a stack, and each thread has a separate stack.

The storage class of a, b, and c are (implicitly) auto which usually means on the call stack. They don't "inherit" static storage class from the method signature (which is a different meaning of static (yay for grossly overloaded keywords!)).

No, a, b, and c are not static.
Here's a sample that illustrates this:
class Val
{
public:
Val() { cout << "Val" << this << endl; }
~Val() { cout << "~Val" << this << endl; }
int n_;
};
class A
{
public:
static int test()
{
Val a;
a.n_ = rand();
Val b;
b.n_ = rand();
Val c;
c.n_ = a.n_ + b.n_;
return c.n_;
}
};
int main()
{
srand(time(0));
for( int i = 0; i < 5; ++i )
{
cout << "Test = " << A::test() << endl;
}
return 0;
}

Related

Using variables in a function from another function

In function foo() there is a loop that iterates until it finds an optimum set of variables and determines that as the ideal set. The function only returns one variable, in order to pass a unit test.
In the next function bar(), I need to output all of the variables in function foo() as it iterates. First output the optimum set of variables, and then the rest of the possible variable sets seperately.
int foo(int a, int b) {
int c, d;
while ( etc. ) {
c = arithmetic_for_c;
d = arithmetic_for_d;
e = c + d;
}
return e;
}
int bar(a, b) {
cout << e;
cout << c << d;
}
This example is very simple, but you get the idea.
I have a feeling references (int&, string& etc) would help somehow, but I'm not sure how they would be used here.
I tried to put together a global array but that seemed to get a bit too complex for the scope of this assignment.
The loop is a necessity, but also seems to ruin any hope for variables or arrays in the global scope.
Unfortunately there are a number of things we haven't learned yet, so there is likely a solution I can't use yet.
Thoughts?
Thank you!
Unless you want to go really fancy (probably not within your reach, yet), foo() has to help bar() a little.
Since you want to show the end result first, then the intermediate data later, you will have to find some way of storing the intermediate states. You could do so, using arrays or lists and push the intermediate values into them.
But another, probably shorter option is, to just store the intermediate output.
You know how to use std::cout by now, which prints output to the console.
It is of type std::ostream. And next to output to a console (or file etc.), the c++ standard library also allows to output to a string.
So, for your use case to work, you create such a string stream, then call bar and give it as output stream the string stream.
At the end of your calculations, you call bar with the regular output stream to print the end result, then, you output the string of the string stream to the regular output stream.
It sounds more convoluted, than it actually is, if you see it in code:
#include <iostream>
#include <sstream>
void bar(int a, int b, int c, int d, int e, std::ostream& os) {
os
<< "a: " << a
<< " b: " << b
<< " c: " << c
<< " d: " << d
<< " e: " << e
<< std::endl;
}
int foo(int a, int b, std::ostream& os ) {
std::ostringstream ossteps;
int c= 0;
int d= 1;
int e= 42;
while (c < 10) {
bar(a,b,c,d,e,ossteps);
c++;
d += c*c;
e = (a * b) - d;
}
bar(a,b,c,d,e,os);
os << ossteps.str();
return e;
}
int main (int argc, const char* argv[]) {
int efinal = foo(1,2, std::cout);
return 0;
}
If I'm not mistaken, this is not really possible in C++, as the variables are declared in the scope of the function foo, and cannot be accessed from a different scope. But you can always use something like this:
Pass by reference (out parameters):
#include <iostream>
// Declaring bar earlier as it has to be accessed by foo
int bar(int& c, int& d) {
int e = 0; // Declaring and initializing variable e
int count = 0;
// Loop
while (count < 10) {
c++;
d += 2;
e = c + d;
count++;
}
return e; // Return variable e
}
int foo(int a, int b) {
int c, d;
c = a, d = b; // setting c = parameter a, d = parameter b
int e = a + b;
std::cout << c << d << std::endl; // Printing variables c and d
std::cout << e << std::endl; // Printing variable e
e = bar(c, d); // Calling bar function. Also this function increments c by 10 and d by 20.
std::cout << c << d << std::endl; // Printing variables c and d
std::cout << e << std::endl; // Printing variable e
return e; // Return variable e
}
int main() {
foo(10, 20); // Calling function 'foo'
}
This is just an example.
The CPU is performing one thread at a specific time. So it can only perform the code in function foo or the function bar, but never both. The scope of the variables in the function are called local or auto variables. They are valid only in the context of the execution of the function. At language level you will say they go out of scope at the closing } bracket. Technically, the memory for the variable is allocated temporarily while entering the function and automatically released on exit. It's just a memory location on the stack. The live time of the variable ends at the end of scope.
So, you must always look at the scope of a variable. You can't access anything temporarily allocated on a different function's stack. The game changes if one function calls another. You can pass a reference from the calling function to the called function, but not the other way.
int foo(int a, int b, int& c, int& d) {
while ( etc. ) {
c = arithmetic_for_c;
d = arithmetic_for_d;
e = c + d;
}
return e;
} // scope of the reference c and ends here,
// but not the scope of the referenced variables.
int bar(a, b) {
int c, d;
// here you define the role of calling function and called function.
int e = foo(a, b, c, d);
cout << e;
cout << c << d;
} // scope of c and d ends here.

Why isn't the static variable getting modified

I'm creating a static variable 'a' inside a member function getobj() and returning it by reference and capture the reference in b. And I modify the same static variable 'a' in another member function mod(). When I print b, I should be expecting '2' right? Why isn't the static variable 'a' not modified to 2?
#include <iostream>
using namespace std;
class Test {
public:
int& getobj() {
static int a = 1;
return a;
}
void mod() {
static int a = 2;
}
};
int main(int arc, char* args[]) {
Test t;
int &b = t.getobj();
cout << "printing b first time and its value is expected : " << b << endl;
t.mod();
cout << "printing b second time after modifying and its value has not changed : " << b << endl;
return 0;
}
Output observed is
printing b first time and its value is expected : 1
printing b second time after modifying and its value has not changed : 1
The variable a in getobj() and the variable a in mod() are in different scope and are different things.
Therefore, modification to a in mod() won't affect a in getobj().
You could achieve your aim with the following piece of computational devilry:
void mod() {
static int& a = getobj();
a = 2;
}
Currently you have two different ints, both with static storage. Changing one will not change the other.
But did you want to use a class member variable instead (which is the normal thing to do), perhaps even without static storage duration?

If multiple classes have a static variable in common, are they shared (within the same scope?)

I have the following example code:
class A {
public:
static int a;
};
int A::a = 0;
class B {
public:
static A a1;
};
A B::a1;
class C {
public:
static A a1;
};
A C::a1;
int main(int argc, const char * argv[]) {
C::a1.a++;
B::a1.a++;
std::cout << B::a1.a << " " << C::a1.a << std::endl;
return 0;
}
Class B and C have class A as a static member variable.
I expected the program to print "1 1", however it prints "2 2".
If multiple classes have a static variable in common, are they shared (within the same scope?)
The static members belong to class, it has nothing to do with objects.
Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program.
For your code, there's only one A::a, which is independent of B::a1 and C::a1 (which are objects of class A). So both B::a1.a and C::a1.a refer to A::a.
You're not looking at multiple classes here. Both B::a1 and C::a1 are of type A. And A has a static variable a, that you accessed twice. If you also wrote A::a++, your program would have printed 3 3
To modify your example slightly:
struct A
{
static int a;
int b;
};
int A::a;
struct B
{
static A a1;
};
A B::a1{0};
struct C
{
static A a2;
};
A C::a2{0};
and the user code:
B::a1.a = 1; // A's static variable changed
B::a1.b = 2; // B's A's b changed to 2
cout << B::a1.a << ", " << B::a1.b << endl;
cout << C::a2.a << ", " << C::a2.b << endl;
It will print:
1, 2
1, 0
That's because all As share a, but all As have their own b. And both C and B have their own A (that they respectively share between objects of their type)
B and C both have static instances of A, these are seperate instances of A and would have different seperate instances of it's members as well. However, A::a is a static variable that is shared between all instances of A so:
&B::a1 != &C::a1 (the two a1 are seperate)
but
&B::a1.a == &C::a1.a (i.e. all A::a are the same, no matter the 'enclosing' instance of A)

static object initializer C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
file scope and static floats
What are static variables?
Here is a code from a book.
class X
{
int i;
public:
X(int ii = 0) : i(ii) {cout<<i<<endl;} // Default
~X() { cout << "X::~X()" << endl; }
};
void f()
{
static X x1(47);
static X x2; // Default constructor required
}
int main()
{
f();
return 0;
}
My question is why would I like to declare an object as static like in function f()? What would happen if I did not declare x1 and x2 as static?
For this code it makes no difference to the observable behavior of the program.
Change main to call f twice instead of only once, and observe the difference -- if the variables are static then only one pair of X objects is ever created (the first time f is called), whereas if they're not static then one pair of objects is created per call.
Alternatively, change main to print something after calling f. Then observe that with static, the X objects are destroyed after main prints (the static objects live until the end of the program), whereas without static the objects are destroyed before main prints (automatic objects only live until exit from their scope, in this case the function f).
The first time the function f() is hit the statics will be initialized (lazy loading). Had they not been declared static then they would be local variables and recreated every time you called function f().
All calls to f() will result in using the same x1 and x2.
The difference between
int f()
{
int i = 0;
++i;
return i;
}
int f2()
{
static int i = 0;
++i;
return i;
}
int main()
{
for (int i = 0; i < 10; ++i) { cout << f1() << ' ' << f2() << endl; }
}
Is that f1 will always make a new local variable i and set it to zero then increment it, while f2 will create a static local variable i and initialize it to zero once and then each call it increments it from the previous call value.
Here is some code to test what does a static object within a function mean:
#include <iostream>
using namespace std;
class A {
public:
void increase() {
static int b = 0;
b++;
cout << "A::increase: " << b << endl;
}
};
int main() {
A a;
a.increase();
a.increase();
a.increase();
return 0;
}
And the output is:
A::increase: 1
A::increase: 2
A::increase: 3
Notice the value of b is kept between function calls? Here is the example on ideone so that you can play with it.

Dependent variables in C++?

I tried asking before but I wasn't very clear so I'm re-asking it.
I want to have a variable that depends on the value of another variable, like b in this example:
int main(){
int a;
dependent int b=a+1; //I'm just making this up
a=3;
cout << b; //prints 4
a=4;
cout << b; //prints 5
}
Of course, this does not exist in C++, but this is what I want.
So instead I tried making a function:
int main(){
int a;
int b(){ return a+1; } //error
a=3;
cout << b(); //would print 4 if C++ allowed nested functions
a=4;
cout << b(); //would print 5 if C++ allowed nested functions
}
The above doesn't work because C++ doesn't allow nested functions.
I can only make functions outside of main(), like this:
int b(){
return a+1; //doesn't work because a is not in scope
}
int main(){
int a;
a=3;
cout << b();
a=4;
cout << b();
}
But this does not work because a is not in the same scope as b(), so I would have to pass a as a parameter and I don't want to do that.
Are there any tricks to get something similar to a dependent variable working in C++?
What you need is a closure. If you can use C++ 0x features, you are in luck. Otherwise, you can define one manually:
#include <iostream>
using namespace std;
struct B
{
const int & a;
B(const int & a) : a(a) {}
// variable syntax (Sean Farell's idea)
operator int () const { return a + 1; }
// function syntax
int operator () () const { return a + 1; }
};
int main()
{
int a;
B b(a);
a = 3;
cout << b << '\n'; // variable syntax
a = 4;
cout << b() << '\n'; // function syntax
}
You can also define B inside main, but some compilers would not like it.
The C++ 0x lambda syntax looks like this:
auto b = [&]() { return a + 1; }
The [&] means that the lambda captures local variables by reference.
If you're using C++0x (GCC 4.5+, Visual C++ 2010), you can use lambdas:
int a = 5;
auto b = [&a]{ return a + 1; };
std::cout << b() << std::endl;
Depending on what you're doing, though, there are probably cleaner solutions - possibly some variation of the classic "method that takes in 'a' and returns 'b'"
You could define a class that had a member a, and then a function b() that returned the value of a+1. A basic implementation would be something like:
class Dependent {
public:
Dependent(void) { m_value = 0; }
void set(int value) { m_value = value; }
int b(void) { return(m_value + 1); }
private:
int m_value;
};
int main(){
Dependent a;
a.set(3);
cout << a.b();
a.set(4);
cout << a.b();
}
You could add operator overloading as appropriate to make it work more like normal integers if you so desired.
This is possible if you use lambda functions (c++0x), because they can capture local variables.
Example:
int main()
{
int a;
auto f = [&] () -> int { return a + 1; };
a = 3;
std::cout << f() << std::endl;
a = 4;
std::cout << f() << std::endl;
return 0;
}
Result:
4
5
(See http://ideone.com/MlzX7 for proof)
A simple approach is to use pre-processor macros, nothing C++ specific about it though:
#define b ((a)+1)
int main(){
int a;
a=3;
cout << b;
a=4;
cout << b;
}
#undef b
Are you OK using C++0x ? if yes,
int main()
{
int a = 10;
auto b = [&a]() -> int { return a + 1; };
cout << b() << endl;
}
Since, it is not tagged with c++0x, you can use nested classes instead of nested functions. This column from Herb sutter would help you for existing c++. http://www.gotw.ca/gotw/058.htm
The above doesn't work because C++ doesn't allow nested functions.
You can simulate that using nested structure. In C++0x you can make use of lambda function, which provides the same means of function inside function.
Define a class called LinkedInt or something that behaves like an int, but has a RelatedTo relationship on itself and an additional member that is a function pointer to the function to evaluate when computing the integer's value. Pretty straightforward. Let me know if you need some pointers on the coding.
The short answer is that OOP is more than enough to bury this problem.
I want to have a variable that depends on the value of another
variable, like b in this example:
I see you just need a reference variable:
int a;
int &b =a;
a=10;
cout << b; // 10
Why C++0x lambdas do come for this, I dont understand.