Thursday 15 June 2017

c++ - Undefined reference when using lambda




The following code produces undefined reference error on c++ (Debian 4.7.2-5) 4.7.2:



#include 

class Lol {
public:
void foo() {
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);

sa.sa_handler = [](int) {
};
sigaction(SIGTERM, &sa, 0);
}
};

int main() {
Lol l;
l.foo();
}




lev@debi7:~$ c++ -std=c++11 -o lol lol.cpp

/tmp/ccWFXAT9.o: In function `Lol::foo()::{lambda(int)#1}::operator void (*)(int)() const': lol.cpp (.text._ZZN3Lol3fooEvENKUliE_cvPFviEEv[_ZZN3Lol3fooEvENKUliE_cvPFviEEv]+0 9): undefined reference to `Lol::foo()::{lambda(int)#1}::_FUN(int)' collect2: error: ld returned 1 exit status



lev@debi7:~$ c++ --version

c++ (Debian 4.7.2-5) 4.7.2


However it compiles/links perfectly fine on g++-4.7.real (Ubuntu/Linaro 4.7.4-3ubuntu3) 4.7.4.



What is going on here?


Answer



There's nothing wrong with the shown code. This was, obviously, a compiler bug. It's not uncommon with community Linux distributions, like Debian, to package upstream code like gcc, as is, without backporting additional fixes from subsequent patchlevels. The last component of gcc's version indicates the patch/fix level. 4.7.4 is two patchlevels after the 4.7.2 compiler, that exhibits this bug.



gcc's support for C++11 was still maturing, during the 4.7 series, and was mostly incomplete. I would be surprised if there weren't any C++11-related bugs, in the 4.7 branch, at that time. If one was to sift through the changelogs between 4.7.2 and 4.7.4, I'm sure there will be an obscure entry, somewhere in there, indicating a bug fix that applies to the use case here.




If you need robust support for C++1x, you need to roll up to the current 5.3 gcc.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...