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.

Reply via email to