#include <iostream>
void foo(int k) {
static auto bar = [&]{
std::cout << k << std::endl;
};
bar();
}
int main () {
foo(1); foo(2); foo(3); // output is correct: 1, 2, 3
}
Check the function foo, an how the static lambda is capturing k by reference. This seems to work, and the same is happening with more complicated datatypes rather than int.
Is this expected? Is there any guarantee that the address of k will be the same for every invocation of foo, or is this UB?
Thanks in advance, and sorry if this was previously answered (I did try to find a similar question without success)
A static variable means that there is only one instance of it; compared to a member variable, for which there will be one variable for each instance of that class. It's nothing to do with passing by reference.
The static keyword in C is a storage-class specifier. It has different meanings, depending on the context. Inside a function it makes the variable to retain its value between multiple function calls. Outside of a function it restrains the visibility of the function or variable to the current file (compilation unit).
It is Undefined Behavior.
Per Paragraph 5.2.2/4 of the C++11 Standard about function call expressions and the initialization of their parameters:
[...] The lifetime of a parameter ends when the function in which it is defined returns. The initialization and destruction of each parameter occurs within the context of the calling function. [...]
Therefore, your lambda will be storing a reference that becomes dangling as soon as the function call returns.
In this case, implementations are free (and likely) to create function parameters at the same address for each function call, which is probably the reason why you are observing the expected output.
However, this behavior is not mandated by the Standard - therefore, you should not rely on it (if this was the case, your code would be legal because of 3.8/7).
The reason it's probably "working" in your example is that the call stack is always lining up the same way. Try this instead and see if you still get the "expected" output.
#include <iostream>
void foo(int k) {
static auto bar = [&]{
std::cout << k << std::endl;
};
bar();
}
void baz(int k) {
std::cout << "baz: ";
foo(k);
}
int main () {
foo(1); baz(2); foo(3);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With