https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61402
Bug ID: 61402
Summary: [C++1y] Init-capture with side effect not working for
some types
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: thibaut.lutz at googlemail dot com
Lambda functions with an init-capture for which the initializer has a side
effect is not always taken into account.
The example below defines a lambda with an init-capture, which increments a
variable in the initalizer, and invoke the lambda immediately with the same
variable as a parameter. The body of the lambda prints the value of the
captured value and its parameters, which should be identical.
Expected result: The captured value and the parameter should have the same
value, since the instantiation of the lambda should be evaluated before its
invocation.
Actual results: for some types (at least bool and char), the increment inside
the init-capture is partially evaluated: the captured value is correct but the
side effect is gone. Other types are working as expected.
Tested with: gcc 4.9.0 and 4.8.1
Code:
--8<----8<----8<----8<----8<----8<--
#include <iostream>
template<typename T>
void foo(T t) {
using namespace std;
// print the original argument
cout << endl << "par t = " << t << endl;
{ // lambda function declaration and invocation
// capture argument by-copy after pre-increment
[ i = ++t ]
// take one parameter
(T v)
{
// print captured value and argument
cout << "cap i = ++t = " << i << endl
<< "arg v = " << v << endl;
}
// invocation with the new value of the argument
(t);
}
}
int main(){
foo(3.14f); // works OK
foo(0); // works OK
foo('a'); // fails!
foo(false); // fails!
}
--8<----8<----8<----8<----8<----8<--
Program output:
par t = 3.14
cap i = ++t = 4.14
arg v = 4.14
par t = 0
cap i = ++t = 1
arg v = 1
par t = a
cap i = ++t = b
arg v = a
par t = 0
cap i = ++t = 1
arg v = 0
For the last two types (char and bool), we observe v == t instead of v == i.