Static short reference yields an error in recursive function - c++

Here's the whole source:
#include <iostream>
void recursion(static short &di);
using namespace std;
int main()
{
short pi = 1;
for(pi; pi > 0; pi++)
{
cout << "Hi, pi!" << "\n";
recursion(pi);
}
}
void recursion(static short &di)
{
di++;
if(di < 20)
{
return;
}
else
{
cout << di << "\n";
}
}
For some reason it works fine when the 16-bit container isn't static, but I want it to be static, and it gives the following error:
main.cpp:2:29: error: storage class specifiers invalid in parameter declarations
void recursion(static short di);
^
main.cpp:2:29: error: storage class specified for parameter 'di'
main.cpp:14:29: error: storage class specifiers invalid in parameter declarations
void recursion(static short di)
^
main.cpp:14:29: error: storage class specified for parameter 'di'

You can't specify a static storage duration for function parameters.
You can still pass a reference to a static varibale to a function, and the reference will still refer to a static variable.
For example:
int main()
{
static short pi = 1;
// ^^^^^^
for(pi; pi > 0; pi++)
{
cout << "Hi, pi!" << "\n";
recursion(pi);
}
// ...
}
void recursion(short &di)
{
// ...
}
But in your case making pi a static seems rather pointless.
You might not fully understand what a static storage duration means, so I'll take the liberty to explain.
Normally you declare variable without the static qualifier like this:
void foo()
{
int myValue = 42;
}
A varibale declared like this has automatic storage duration; meaning when it "goes out of scope", the object is destroyed. If you were to call foo() 100 times:
int main()
{
for (int i = 0; i < 100; ++i)
foo();
}
...then myValue would be re-initialized 100 times. Normally this is exactly what you want.
Sometimes you want a variable to outlive the scope in which it's declared. To accomplish this, you give it static storage duration, using the static keyword:
void foo()
{
static int myValue = 42;
}
A variable declared this way will be initialized exactly once, before it's first usage, and will continue to live even after its gone out of scope. It will retain it's value until it's been reassigned, until the program ends.
Your code:
int main()
{
short pi = 1;
for(pi; pi > 0; pi++)
{
cout << "Hi, pi!" << "\n";
recursion(pi);
}
}
establishes the pi variable, and then calls recursion a number of times. Here pi does not need static storage duration, because it will never go out of scope during the loop where you call recursion. All you have to do is pass a reference to pi to recursion, and it will behave as you intend.

The error message is quite explicit; you cannot have a static qualifier for a formal argument; you need to declare
void recursion(short &di);
and later to define
void recursion(short &di) {
di++;
if(di < 20)
return;
else
cout << di << "\n";
}

Related

Why is a C++ lambda life cycle bound to the smallest block scope?

In the following example program, I would expect the counter to reset at the beginning of each cycle:
#include <iostream>
#include <functional>
void run_lambda(std::function<void()> fun){ fun(); fun(); }
int main(){
for(int i = 0; i < 3 ; ++i){
run_lambda([i](){
static int testVal = 0;
std::cout << "value[" << i << "]:" << testVal << std::endl;
++testVal;
});
}
return 0;
}
Instead the output is:
value[0]:0
value[0]:1
value[1]:2
value[1]:3
value[2]:4
value[2]:5
According to this answer:
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.
In my understanding this means, that the lambda object life cycle is bound to the loops block scope, thus the static variable is not resetting at the start of the loop.
Is there a specific reason for this? Intuitively one would think that a lambda expression is essentially a temporary object, and as such in this example it would cease to exist after the statement.
Your code is basically equivalent to:
#include <iostream>
#include <functional>
struct lambda
{
lambda(int i): i(i) {}
int i;
void operator()()
{
static int testVal = 0;
std::cout << "value[" << i << "]:" << testVal << std::endl;
++testVal;
}
};
void run_lambda(std::function<void()> fun){ fun(); fun(); }
int main(){
for(int i = 0; i < 3 ; ++i){
lambda l{i};
run_lambda(l);
}
return 0;
}
Whilst each iteration of the loop does indeed create a new lambda object each object is an instance of the same class and therefore shares the same static variables.
The statement you're quoting is saying that the type is declared inside the scope where the lambda is declared. It isn't saying that each time the code enters that scope a new type is created (c++ doesn't have dynamic types like that).

C++ Recursion Stack Frame Identifier

Take an example:
int foo(){
if(<THIS IS THE SECOND TIME YOU CALL FOO>) // I need some indicator like this
return 1;
else
return foo();
}
Essentially, I'm looking for an indicator that tells me "hey this is the second time that you have called foo". (I'm trying to avoid using static variables or changing foo function itself, just for sake of this exercise.)
I'm guessing if there's any variable related to the function's current stack frame (or maybe the caller stack frame) which I can exploit and use?
You can leverage a thread_local counter, along with a RAII object to increment a counter at some point in your function and decrement it when the thread leaves the function.
By creating an instance of this object with automatic storage duration (as a local variable) near the top of the function you can know how many times the current thread has called the function without returning yet.
By including an auto template argument, you can also provide the function as the template argument to allow the class to be reused in different functions.
Live example :
template<auto>
class stack_count
{
public:
stack_count() {
counter()++;
}
~stack_count() {
counter()--;
}
stack_count(const stack_count&) = delete;
void operator=(const stack_count&) = delete;
int get() const {
return counter();
}
private:
static int & counter() {
thread_local int counter = 0;
return counter;
}
};
#include <iostream>
int foo()
{
stack_count<&foo> counter;
std::cout << counter.get() << '\n';
if(counter.get() == 2) {
return 42;
}
else {
return foo();
}
}
int main()
{
const auto result = foo();
std::cout << "foo() : " << result << '\n';
}
I'm assuming you want to detect when foo has been called recursively, not when it's been called twice.
And I am guessing you're trying to avoid changing the function signature of foo, but can do whatever you want with the implementation. If that's the case, an inner "implementation" (impl) function that lets you pass the recursion count. The original function foo just calls the implementation function with a seed value:
int fooImpl(int count) {
if (count == 2) {
// this is the second time you've called foo
return 0; // return any value you want
} else {
return fooImpl(count+1);
}
}
int foo(){
return fooImpl(1);
}
And if you don't want to escape the bounds of the function, then use an internal lambda:
int foo() {
std::function<int(int)> fn;
fn = [&fn](int count)->int {
if (count == 2) {
// this is the second time you've called foo
return 0; // return any value you want
}
else {
return fn(count + 1);
}
};
return fn(1);
}

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?

Can a function safely return a reference to an internal static variable?

Is it valid when a function returns by reference its own internal static variable?
const int& f() {
static int n=10;
return n;
}
Yes, there is nothing wrong with this. In particular, the static variable isn't destroyed when the function exits, so it doesn't return a dangling reference (as it would if n was not static).
Just keep in mind that it's a static variable, so for example in this:
#include <iostream>
const int& f(int x) {
static int n;
n = x;
return n;
}
int main() {
const int &a = f(1);
const int &b = f(2);
cout << a << " " << b;
}
a and b refer to the same variable, so this prints "2 2" and not "1 2".
This is fine. The static variable will be initialized the first time the function is executed, and will survive beyond the function's return.

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.