Evet, bu Clang ++ 'da bir hatadır. Ben i386-pc-linux-gnu'da CLang 3.2 ile yeniden üretebilirim. Böcek işaretçisi-to-işlevine labmda dönüşüm olduğunu tespit ettik
Ve şimdi bazı rasgele analiz
...: derleyici
bir tür uygun imzayla düşünebilirdi oluşturur lambda çağırır, ancak
ret
yerine
ud2
talimatı vardır.
Muhtemelen bildiğiniz gibi ud2
talimatı, "Geçersiz Opcode" istisnasını açık bir şekilde yükselten bir talimattır. Yani, kasıtlı olarak tanımlanmamış bir talimat.
Çıkartılması bir göz atın: Yani hata minimal örnek basitçe olacak
main::$_0::__invoke():
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
movl %ecx, 4(%esp)
calll main::$_0::operator()() const ; this calls to the real lambda
subl $4, %esp
ud2 ; <<<-- What the...!!!
: tuhafı
int main() {
std::string(*f)() = []() -> std::string {
return "bla";
};
f();
return 0;
}
, hata yapmaz bu thunk fonksiyonudur Dönüş türü int
gibi basit bir türse, gerçekleşir. Sonra oluşturulan düşünebilirdi geçerli:
main::$_0::__invoke():
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl %eax, (%esp)
calll main::$_0::operator()() const
addl $8, %esp
popl %ebp
ret
Sorun dönüş değerinin yönlendirme olduğunu sanıyorum. eax
gibi bir kayıt defterine sığarsa her şey iyi gider. Ancak, std::string
gibi büyük bir yapı ise yığın içinde döndürülürse, derleyici karışıktır ve çaresizlik içinde ud2
yayar.
Clang –
FYI'de bir hata olduğunu söyleyebilirim, [ud2 ve clang] hakkında daha fazla bilgi (http://stackoverflow.com/q/26309300/1708801) –