mercredi 4 février 2015

C++11: buggy lambda behavior

Consider this C++11 code snippet:



#include <iostream>
#include <set>
#include <stdexcept>
#include <initializer_list>


int main(int argc, char ** argv)
{
enum Switch {
Switch_1,
Switch_2,
Switch_3,
Switch_XXXX,
};

int foo_1 = 1;
int foo_2 = 2;
int foo_3 = 3;
int foo_4 = 4;
int foo_5 = 5;
int foo_6 = 6;
int foo_7 = 7;

auto get_foos = [=] (Switch ss) -> std::initializer_list<int> {
switch (ss) {
case Switch_1:
return {foo_1, foo_2, foo_3};
case Switch_2:
return {foo_4, foo_5};
case Switch_3:
return {foo_6, foo_7};
default:
throw std::logic_error("invalid switch");
}
};

std::set<int> foos = get_foos(Switch_1);
for (auto && foo : foos) {
std::cout << foo << " ";
}
std::cout << std::endl;
return 0;
}


Whatever compiler I try to test it seems all handle it incorrectly. So this makes me think that I am doing something wrong rather than it's a common bug across compilers.


clang 3.5 output:



-1078533848 -1078533752 134518134


gcc 4.8.2 output:



-1078845996 -1078845984 3


gcc 4.8.3 output (compiled on http://ift.tt/PopmyC):



1 2 267998238


gcc (unknown version) outoput (compiled on http://ift.tt/1c5pPp7)



-1785083736 0 6297428


The problem seems to be caused by using std::initializer_list<int> as a return value of lambda. When changing lambda definition to [=] (Switch ss) -> std::set<int> {...} returned values are correct.


Please, help me solve this mystery.


Aucun commentaire:

Enregistrer un commentaire