{"id":388405,"date":"2024-06-29T07:55:30","date_gmt":"2024-06-29T07:55:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=388405"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T07:55:30","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=388405","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0432 C++<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2a6\/e1f\/d68\/2a6e1fd68d5f45890973c88959ad3f2d.png\" alt=\"\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f!\" title=\"\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f!\" width=\"764\" height=\"433\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2a6\/e1f\/d68\/2a6e1fd68d5f45890973c88959ad3f2d.png\"\/><figcaption>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f!<\/figcaption><\/figure>\n<p>C++ &#8212; \u043e\u0434\u0438\u043d \u0438\u0437 \u044f\u0437\u044b\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c &#171;\u043b\u0435\u0433\u0435\u043d\u0434\u0430\u0440\u043d\u044b\u043c&#187;. \u0415\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u0438\u0439, \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u043c \u0440\u0435\u0432\u043e\u043b\u044e\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u043d\u0435 \u0440\u0430\u0437, \u0430 <a href=\"http:\/\/open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2021\/n4892.pdf\" rel=\"noopener noreferrer nofollow\">\u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a<\/a> \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u0443\u0436\u0435 \u0440\u0430\u0437\u0440\u043e\u0441\u0441\u044f \u0434\u043e 1800+ \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043c\u0435\u043b\u043a\u043e\u0433\u043e \u0448\u0440\u0438\u0444\u0442\u0430.<\/p>\n<p>\u041d\u0430 C++ \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041d\u043e \u043d\u0435\u0440\u0435\u0434\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0434\u0435\u043b\u0430\u043b\u0438 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043c\u0435\u043d\u0435\u0435 \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u043c\u0438 \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c\u0438 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u0432 \u0441\u0430\u043c\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u041f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0438\u043c\u0435\u044e\u0442 \u043d\u0435\u0441\u043e\u0438\u0437\u043c\u0435\u0440\u0438\u043c\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435, \u0447\u0435\u043c \u043b\u044e\u0431\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0432 \u0443\u0447\u0435\u0431\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043b\u044f C++ \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 <code>defer<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0432 \u044f\u0437\u044b\u043a\u0430\u0445 Go \u0438 Swift. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0430\u0432\u043a\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 Clang.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5d9\/12c\/21b\/5d912c21b323cd16a65c62ca6ea695a9.png\" alt=\"\u041c\u0430\u0441\u043a\u043e\u0442 LLVM \u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u043b\u0430\u043f\u0430\u0445 C++\" title=\"\u041c\u0430\u0441\u043a\u043e\u0442 LLVM \u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u043b\u0430\u043f\u0430\u0445 C++\" width=\"1024\" height=\"1024\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5d9\/12c\/21b\/5d912c21b323cd16a65c62ca6ea695a9.png\"\/><figcaption>\u041c\u0430\u0441\u043a\u043e\u0442 LLVM \u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u043b\u0430\u043f\u0430\u0445 C++<\/figcaption><\/figure>\n<h2>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b defer<\/h2>\n<p>\u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 Go \u0438 Swift, \u0435\u0441\u0442\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e defer. \u0412 Go \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 (exceptions), \u043d\u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0434\u0438\u043e\u043c\u0430 \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 &#8212; \u043f\u0440\u044f\u043c\u043e\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u044f\u0437\u044b\u043a\u0443 \u0432\u044b\u0437\u0432\u0430\u0442\u044c cleanup-\u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0432\u044b\u0445\u043e\u0434\u0443 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<pre><code class=\"go\">func write(fileName string, text string) error {     file, err := os.Create(fileName)     if err != nil {         return err     }     defer file.Close()     \/\/ ... \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e return-\u043e\u0432, file.Close() \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, C++ \u043d\u0435 \u043d\u0443\u0436\u0435\u043d <code>defer<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0438\u0434\u0438\u043e\u043c\u0430 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/raii\" rel=\"noopener noreferrer nofollow\">RAII<\/a>. \u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u043c C++-\u043a\u043e\u0434\u0435 \u0431\u044b\u043b \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043d\u0435\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 <code>os.Create<\/code> \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435, \u0430 <code>file.Close()<\/code> \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435. \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>defer<\/code> \u0432 \u044d\u0442\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u0441\u0451\u0442 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440.<\/p>\n<hr\/>\n<h2>defer \u0432 open-source \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445<\/h2>\n<p><code>defer<\/code> \u0441 \u0440\u0430\u0437\u043d\u044b\u043c \u0443\u0441\u043f\u0435\u0445\u043e\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 &#171;\u0440\u0443\u043a\u0430\u043c\u0438&#187;.<\/p>\n<p><a href=\"https:\/\/www.boost.org\/doc\/libs\/1_77_0\/libs\/scope_exit\/doc\/html\/index.html\" rel=\"noopener noreferrer nofollow\">Boost.ScopeExit<\/a> &#8212; \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 <code>defer<\/code>-\u0430. \u041e\u043d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043d\u0430 C++11 \u0432\u043f\u0435\u0440\u0435\u043c\u0435\u0448\u043a\u0443 \u0441 C++03, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0438\u0437\u043b\u0438\u0448\u043d\u0435 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u0430 \u0438 \u043c\u0430\u043b\u043e \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0438.<\/p>\n<p>\u0425\u043e\u0442\u044f Boost &#8212; \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u0435\u0433\u043e \u043a\u0443\u0441\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0430\u0436\u0443\u0440\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0412 Boost <a href=\"https:\/\/www.boost.org\/doc\/libs\/\" rel=\"noopener noreferrer nofollow\">167<\/a> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430. \u041c\u043d\u043e\u0433\u0438\u0435 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043b\u0438\u0431\u043e \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0441 ~2006 \u0433\u043e\u0434\u0430, \u043b\u0438\u0431\u043e \u0441\u0442\u0430\u043b\u0438 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442, \u043b\u0438\u0431\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0442 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443, \u043b\u0438\u0431\u043e \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0432\u043d\u0435 Boost \u0441 \u043b\u0443\u0447\u0448\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c.<\/p>\n<p><a href=\"https:\/\/github.com\/catboost\/catboost\" rel=\"noopener noreferrer nofollow\">CatBoost<\/a> &#8212; \u0432 \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0434\u043b\u044f \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 <a href=\"https:\/\/github.com\/catboost\/catboost\/blob\/master\/util\/generic\/scope.h#L65\" rel=\"noopener noreferrer nofollow\">Y_DEFER<\/a>.<\/p>\n<p>\u041e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e <code>defer<\/code>-\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043a\u0440\u044b\u0442\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u0434. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0445\u0438\u0442\u0440\u043e\u0443\u043c\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">#define Y_SCOPE_EXIT(...) const auto Y_GENERATE_UNIQUE_ID(scopeGuard) Y_DECLARE_UNUSED = ::NPrivate::TMakeGuardHelper{} | [__VA_ARGS__]() mutable -> void #define Y_DEFER Y_SCOPE_EXIT(&amp;)<\/code><\/pre>\n<p><code>Y_GENERATE_UNIQUE_ID(scopeGuard)<\/code> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<p><code>Y_DECLARE_UNUSED<\/code> \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p><code>[__VA_ARGS__]() mutable -> void<\/code> &#8212; \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u043b\u044f \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u0443\u0434\u0430 \u0437\u0430\u043f\u0438\u0448\u0435\u0442\u0441\u044f <code>&amp;<\/code>. <code>mutable<\/code> \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. <code>-> void<\/code> \u044d\u0442\u043e trailing return type, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043b\u044f\u043c\u0431\u0434\u044b.<\/p>\n<p><code>TMakeGuardHelper<\/code> \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0442\u0430\u043a, \u0447\u0442\u043e \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c <code>TMakeGuardHelper{} | &lt;\u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435><\/code>.<\/p>\n<p>\u041c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>defer<\/code>-\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u0435\u0441\u0442\u0430 \u0435\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f &#8212; \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0442\u043e\u0433\u043e scope, \u0433\u0434\u0435 \u043e\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d, \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435:<\/p>\n<pre><code class=\"cpp\">{     A a;     B b;     Y_DEFER { &lt;body> };     C c;     D d;      \/\/ \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u0434...      \/\/ \u0432\u044b\u0437\u043e\u0432 \u043f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 d.~D(), c.~C(), { &lt;body> }, b.~B(), a.~A() }<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u043b\u0430 <code>defer<\/code> \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0440\u043e\u0441\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e <a href=\"https:\/\/habr.com\/ru\/post\/433944\/\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u0443\u0435\u0442 std::terminate<\/a>.<\/p>\n<hr\/>\n<h2>Clang \u0438 LLVM<\/h2>\n<p>\u041f\u0440\u043e \u0441\u0430\u043c\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Clang \u0438 LLVM \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0443\u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439. \u041d\u0430 \u0445\u0430\u0431\u0440\u0435 \u044f \u0431\u044b \u043f\u043e\u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b <a href=\"https:\/\/habr.com\/ru\/company\/huawei\/blog\/511854\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e<\/a>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0445 \u043a\u0440\u0430\u0442\u043a\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0438 \u043e\u0431\u0449\u0443\u044e \u0441\u0445\u0435\u043c\u0443.<\/p>\n<p>\u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c \u043c\u0438\u0440\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0441 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0431\u0435\u0434\u0438\u043b\u0438. Clang \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f\u0445 &#8212; Yandex, Apple, Google (\u0432 \u043d\u0451\u043c 400-450\u043c\u043b\u043d \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430 \u043d\u0430 C++) \u0438 \u0442.\u0434.; \u0442\u0430\u043a \u0438 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 &#8212; FreeBSD, OpenBSD, Android, Chrome, Firefox, LibreOffice \u0438 \u0442.\u0434.<\/p>\n<p>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0434\u0438\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430. \u0410\u043d\u0430\u0442\u043e\u043c\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430 \u0438 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:<\/p>\n<ul>\n<li>\n<p><strong>Front-end<\/strong>: \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a \u0438\u0437 C\/C++\/Ada\/Rust\/Haskell\/&#8230; \u0432 <a href=\"https:\/\/llvm.org\/docs\/LangRef.html\" rel=\"noopener noreferrer nofollow\">LLVM IR<\/a> &#8212; \u043e\u0441\u043e\u0431\u043e\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c \u0434\u043b\u044f C-like \u044f\u0437\u044b\u043a\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>Clang<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Middle-end<\/strong>: LLVM IR \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n<\/li>\n<li>\n<p><strong>Back-end<\/strong>: LLVM IR \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u043e\u0434 \u043d\u0443\u0436\u043d\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 &#8212; x86\/Arm\/PowerPC\/&#8230;<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u043e\u0434 <a href=\"https:\/\/llvm.org\/docs\/tutorial\/MyFirstLanguageFrontend\/index.html\" rel=\"noopener noreferrer nofollow\">1000 \u0441\u0442\u0440\u043e\u043a<\/a> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u044e \u043c\u043e\u0449\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 LLVM &#8212; \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c lex\/yacc &#8212; \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b.<\/p>\n<p>\u041d\u0430 \u043c\u0435\u043d\u0435\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 <strong>Clang<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044f \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 &#171;\u043c\u0438\u043a\u0440\u043e&#187;-\u0448\u0430\u0433\u0438):<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9B%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7\" rel=\"noopener noreferrer nofollow\">\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437<\/a>: \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u0442\u043e\u043a\u0435\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>[]() { return 13 + 37; }<\/code> \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 <code>(l_square) (r_square) (l_paren) (r_paren) (l_brace) (return) (numeric_constant:13) (plus) (numeric_constant:37) (semi) (r_brace)<\/code>.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A1%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7\" rel=\"noopener noreferrer nofollow\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437<\/a>: \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 AST (Abstract Syntax Tree), \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u0432 \u0432\u0438\u0434 <code>(lambda-expr (body (return-expr (plus-expr (number 13) (number 37)))))<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f: \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 LLVM IR \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u043c\u0443 AST.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, &#171;\u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438&#187; \u043e\u0447\u0435\u043d\u044c \u0447\u0435\u0442\u043a\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 Clang \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0433\u0438\u0433\u0430\u043d\u0442\u0441\u043a\u0438\u0435. \u041d\u0430 \u043c\u043e\u0439 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0440\u0430\u0441\u043f\u0443\u0445\u0448\u0438\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441 \u0444\u0430\u043a\u0442\u043e\u043c, \u0447\u0442\u043e C++ &#8212; \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0439 \u044f\u0437\u044b\u043a.<\/p>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Compilers:_Principles,_Techniques,_and_Tools\" rel=\"noopener noreferrer nofollow\">DragonBook<\/a>. Clang \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0435\u0433\u043e, \u043d\u043e C++ \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043e\u043d\u0438\u0442\u044c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 ad-hoc \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 \u0438 \u043a\u043e\u0441\u0442\u044b\u043b\u044f\u043c\u0438.<\/p>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438 \u0441\u0431\u043e\u0440\u043a\u0430 Clang<\/h2>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 <a href=\"https:\/\/clang.llvm.org\/get_started.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0442\u0430\u043a\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code class=\"bash\">git clone https:\/\/github.com\/llvm\/llvm-project.git cd llvm-project &amp;&amp; mkdir build &amp;&amp; cd build cmake -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release ..\/llvm make -j 4<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c <code>make clang -j 4<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0438\u043b\u0434 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e. \u042f \u0432\u044b\u0431\u0440\u0430\u043b release-\u0441\u0431\u043e\u0440\u043a\u0443 <code>-DCMAKE_BUILD_TYPE=Release<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a debug-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u043e\u043b\u044c\u043a\u043e, \u0447\u0442\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a clang \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0435 \u0441\u043b\u0438\u043d\u043a\u0443\u0435\u0442\u0441\u044f (\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043b\u0438\u043d\u043a\u0435\u0440\u0430 \u0443\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e Out-Of-Memory \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0436\u0438\u0440\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043a\u0438), \u043d\u043e \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0432\u0435\u0437\u0442\u0438 \u0441 \u044d\u0442\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f \u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435\u043c debug-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <a href=\"https:\/\/clang.llvm.org\/hacking.html#debugging\" rel=\"noopener noreferrer nofollow\">\u043c\u0435\u0442\u043e\u0434<\/a> <code>dump()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432 stderr. \u0422\u0430\u043a\u0436\u0435, \u0435\u0441\u043b\u0438 \u0441\u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0434\u0435\u043d\u0438\u0435 clang-\u0430, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p>Clang \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0431\u043e\u0440\u043a\u0438 CMake, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 IDE, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0435\u0433\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c.<\/p>\n<hr\/>\n<h2>\u041d\u043e\u0432\u043e\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e defer<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u043e <code>defer<\/code>, Clang \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442 \u0435\u0433\u043e \u043a\u0430\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (\u0442\u043e\u043a\u0435\u043d \u0432\u0438\u0434\u0430 identifier) \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0432 expression), \u0438 \u043a\u043e\u0434 \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0431\u044b\u043b \u0440\u0430\u043d\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d (\u0432 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c declaration).<\/p>\n<pre><code class=\"cpp\">int main() {     defer; }<\/code><\/pre>\n<pre><code>file.cpp:2:5: error: use of undeclared identifier 'defer'     defer;     ^ 1 error generated.<\/code><\/pre>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/main\/clang\/include\/clang\/Basic\/TokenKinds.def\" rel=\"noopener noreferrer nofollow\">clang\/include\/clang\/Basic\/TokenKinds.def<\/a>. \u041f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u0443\u0441\u043a\u0438 Clang-\u0430 \u043c\u043e\u0433\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0438\u043d\u043a\u043b\u044e\u0434\u0438\u0442\u044c \u0438\u0445 \u043a \u0441\u0435\u0431\u0435 \u0432 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043a\u043e\u0434\u0430: <code>#include \"clang\/Basic\/TokenKinds.def\"<\/code>.<\/p>\n<p>Clang \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u0432 \u044f\u0437\u044b\u043a\u043e\u0432 C, C++, Objective-C; \u0434\u043b\u044f \u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0435\u043a \u043d\u0430\u0434 \u044f\u0437\u044b\u043a\u0430\u043c\u0438 OpenMP, OpenCL, CUDA \u0438 \u043f\u0440.; \u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043a\u043e\u0441\u0442\u044b\u043b\u0435\u0439 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0432 \u044f\u0437\u044b\u043a \u043e\u0442 Microsoft, GNU, \u0441\u0430\u043c\u043e\u0433\u043e Clang \u0438 \u043f\u0440.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 Clang \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u0439. \u0415\u0441\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u044d\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043e \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438: <code>ParseExprCXX.cpp<\/code>, <code>ParseOpenMP.cpp<\/code>. \u0421\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 &#8212; \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f \u0432\u0441\u0435\u0445. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0443\u0434\u0430 \u043d\u043e\u0432\u043e\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f C++:<\/p>\n<pre><code class=\"cpp\">KEYWORD(defer                       , KEYCXX)<\/code><\/pre>\n<p>\u0418 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c Clang. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u043a\u0441\u0435\u0440 (\u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440) \u043d\u0430\u0443\u0447\u0438\u043b\u0441\u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u0441\u0440\u0430\u0437\u0443. \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/microsoft\/blog\/458242\/\" rel=\"noopener noreferrer nofollow\">spaceship operator<\/a>, \u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u043b\u0435\u043a\u0441\u0435\u0440: <a href=\"https:\/\/github.com\/llvm\/llvm-project\/commit\/edbf5972a4c912d9e03b6c33ef73872603ca0522#diff-e0caa2ace07c5d0a47aa3d905d2dafe4b14f5bdbfcbbffd40da6aa4c62fee0a9\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u043c\u043c\u0438\u0442 \u0441\u043e spaceship<\/a>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c Clang \u043d\u0435 \u0434\u0443\u043c\u0430\u0435\u0442, \u0447\u0442\u043e <code>defer<\/code> \u044d\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e identifier, \u043d\u043e \u0438 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f:<\/p>\n<pre><code>file.cpp:2:5: error: expected expression     defer;     ^ 1 error generated.<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435\u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u0440\u0441\u0435\u0440\u0435 (\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435) <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/00f8aecf6ef43fa0f4d2cdabeb1140bcfb477423\/clang\/lib\/Parse\/ParseExpr.cpp#L1761-L1763\" rel=\"noopener noreferrer nofollow\">\u0432 Parser::ParseCastExpression<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u043a \u044d\u0442\u043e\u043c\u0443 \u043c\u0435\u0441\u0442\u0443<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> #3 0x000056335ad3d395 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&amp;, clang::Parser::TypeCastState, bool, bool*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54f8395)  #4 0x000056335ad3ff2e clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54faf2e)  #5 0x000056335ad4011d clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54fb11d)  #6 0x000056335ad448ed clang::Parser::ParseExpression(clang::Parser::TypeCastState) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54ff8ed)  #7 0x000056335adbac80 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x5575c80)  #8 0x000056335adaec0e clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector&lt;clang::Stmt*, 32u>&amp;, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributesWithRange&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x5569c0e)  #9 0x000056335adafeca clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector&lt;clang::Stmt*, 32u>&amp;, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x556aeca) #10 0x000056335adb0cf1 clang::Parser::ParseCompoundStatementBody(bool) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x556bcf1) #11 0x000056335adb1862 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x556c862) #12 0x000056335ace6997 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&amp;, clang::Parser::ParsedTemplateInfo const&amp;, clang::Parser::LateParsedAttrList*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54a1997) #13 0x000056335ad163af clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&amp;, clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54d13af) #14 0x000056335ace12fa clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributesWithRange&amp;, clang::ParsingDeclSpec&amp;, clang::AccessSpecifier) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x549c2fa) #15 0x000056335ace1965 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributesWithRange&amp;, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.0) Parser.cpp:0:0 #16 0x000056335ace9543 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributesWithRange&amp;, clang::ParsingDeclSpec*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54a4543) #17 0x000056335acea87d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&lt;clang::DeclGroupRef>&amp;, bool) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54a587d) #18 0x000056335aceae19 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr&lt;clang::DeclGroupRef>&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54a5e19) #19 0x000056335acdb5ca clang::ParseAST(clang::Sema&amp;, bool, bool) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54965ca) #20 0x000056335a018636 clang::CodeGenAction::ExecuteAction() (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x47d3636) #21 0x000056335990bd91 clang::FrontendAction::Execute() (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x40c6d91) #22 0x000056335989c9db clang::CompilerInstance::ExecuteAction(clang::FrontendAction&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x40579db) #23 0x00005633599e6070 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x41a1070) #24 0x0000563356a35f44 cc1_main(llvm::ArrayRef&lt;char const*>, char const*, void*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x11f0f44) #25 0x0000563356a3311b ExecuteCC1Tool(llvm::SmallVectorImpl&lt;char const*>&amp;) driver.cpp:0:0 #26 0x0000563356959dd0 main (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x1114dd0) #27 0x00007f3492a290b3 __libc_start_main \/build\/glibc-eX1tMB\/glibc-2.31\/csu\/..\/csu\/libc-start.c:342:3 #28 0x0000563356a32cbe _start (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x11edcbe)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0430\u0442\u044c <code>defer<\/code> \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043c\u044b\u0441\u043b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0439 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/00f8aecf6ef43fa0f4d2cdabeb1140bcfb477423\/clang\/lib\/Parse\/ParseExpr.cpp#L1656-L1661\" rel=\"noopener noreferrer nofollow\">\u043a\u043b\u044e\u0447\u0435\u0432\u043e\u043c\u0443 \u0441\u043b\u043e\u0432\u0443 new<\/a>, \u043d\u0430\u043f\u0438\u0441\u0430\u0432  <code>case tok::kw_defer:<\/code> \u043f\u043e\u0441\u043b\u0435 <code>case tok::kw_new:<\/code>:<\/p>\n<pre><code class=\"cpp\">  case tok::kw_new: \/\/ [C++] new-expression   case tok::kw_defer: \/\/ [hacked C++] defer-expression     if (NotPrimaryExpression)       *NotPrimaryExpression = true;     Res = ParseCXXNewExpression(false, Tok.getLocation());     AllowSuffix = false;     break;<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u0434\u0443 \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0438:<\/p>\n<pre><code class=\"cpp\">int main() {     int* i = defer int[13];     delete[] i; }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0435 <code>defer<\/code> \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 (compound statement) \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u043d\u0438\u043c, \u0441\u0434\u0430\u043c\u043f\u0438\u0442 \u0435\u0433\u043e AST \u0432 stderr \u0438 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 warning \u043e \u0442\u043e\u043c, \u0447\u0442\u043e defer-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0432 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/fa82a3d016c9fb82c1b81834fa18cd4c797735a0\/clang\/include\/clang\/Basic\/DiagnosticParseKinds.td\" rel=\"noopener noreferrer nofollow\">clang\/include\/clang\/Basic\/DiagnosticParseKinds.td<\/a> \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 warning:<\/p>\n<pre><code>def warn_unimplemented_defer :    Warning&lt;\"defer statements are not implemented yet, ignore it\">;<\/code><\/pre>\n<p>\u0418 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>Parser::ParseCastExpression<\/code>:<\/p>\n<pre><code class=\"cpp\">  case tok::kw_defer: {     SourceLocation DeferLoc = ConsumeToken(); \/\/ skip \"defer\" token     StmtResult DeferredStmt(ParseCompoundStatementBody());     if (!DeferredStmt.isInvalid()) {         DeferredStmt.get()->dump();     }      Diag(DeferLoc, diag::warn_unimplemented_defer);     return ExprError();   }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e \u0430\u0432\u0442\u043e\u043a\u043e\u043c\u043f\u043b\u0438\u0442\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0438 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043a \u043d\u0438\u043c, \u0442\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0435\u0442\u0441\u044f \u0432\u043f\u0435\u0440\u0435\u0434 \u043d\u0430 1 \u0442\u043e\u043a\u0435\u043d (\u0442.\u0435. \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442 \u0441\u043b\u043e\u0432\u043e <code>defer<\/code>), \u043f\u043e\u0442\u043e\u043c \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 (\u0432\u0438\u0434\u0430 <code>{ ... }<\/code>), \u0438 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442 \u0435\u0433\u043e, \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0432 stderr \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u043d\u043e\u0432\u044b\u0439 warning \u043f\u043e\u0434 \u0441\u043b\u043e\u0432\u043e\u043c <code>defer<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0441\u043e\u0431\u0435\u0440\u0435\u043c Clang \u0435\u0449\u0435 \u0440\u0430\u0437. \u0414\u043b\u044f \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0435\u0441\u0442\u044c \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 CMake, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 Clang &#171;\u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0442&#187; \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0443, \u043f\u0435\u0440\u0435\u0434 \u0431\u0438\u043b\u0434\u043e\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u0440\u0430\u0437 <code>cmake -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release ..\/llvm<\/code>.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c Clang \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435:<\/p>\n<pre><code class=\"cpp\">#include &lt;cstdio> int main() {     defer {         int var = 1 + 2;         printf(\"1 + 2 is %d\\n\", var);     };     printf(\"hello world!\\n\"); }<\/code><\/pre>\n<pre><code>izaron@izaron:~\/check$ ~\/hack\/llvm-project\/build\/bin\/clang++ file.cpp  CompoundStmt 0x560115cc6e80 |-DeclStmt 0x560115cc6c68 | `-VarDecl 0x560115cc6ba0  used var 'int' cinit |   `-BinaryOperator 0x560115cc6c48 'int' '+' |     |-IntegerLiteral 0x560115cc6c08 'int' 1 |     `-IntegerLiteral 0x560115cc6c28 'int' 2 `-CallExpr 0x560115cc6e20 'int'   |-ImplicitCastExpr 0x560115cc6e08 'int (*)(const char *__restrict, ...)' &lt;FunctionToPointerDecay>   | `-DeclRefExpr 0x560115cc6d90 'int (const char *__restrict, ...)' lvalue Function 0x560115cac748 'printf' 'int (const char *__restrict, ...)'   |-ImplicitCastExpr 0x560115cc6e50 'const char *' &lt;ArrayToPointerDecay>   | `-StringLiteral 0x560115cc6d48 'const char [13]' lvalue \"1 + 2 is %d\\n\"   `-ImplicitCastExpr 0x560115cc6e68 'int' &lt;LValueToRValue>     `-DeclRefExpr 0x560115cc6d70 'int' lvalue Var 0x560115cc6ba0 'var' 'int' file.cpp:3:5: warning: defer statements are not implemented yet, ignore it     defer {     ^ 1 warning generated. izaron@izaron:~\/check$ .\/a.out  hello world!<\/code><\/pre>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e, printf \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u043e std::cout \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0445 AST.<\/em><\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c defer?<\/h2>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e, \u043d\u043e \u043e\u043d\u043e \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e. \u041d\u0430\u0434\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0438\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h4>\u0410\u0442\u0440\u0438\u0431\u0443\u0442 cleanup<\/h4>\n<p>\u041f\u0440\u043e \u044d\u0442\u043e\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/post\/503536\/\" rel=\"noopener noreferrer nofollow\">\u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u041a \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u043b\u044e\u0431\u043e\u0433\u043e \u0442\u0438\u043f\u0430) \u043c\u043e\u0436\u043d\u043e &#171;\u043f\u0440\u0438\u0446\u0435\u043f\u0438\u0442\u044c&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u0442\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 scope.<\/p>\n<pre><code class=\"cpp\">#include &lt;iostream>  struct dummy_t {     dummy_t() {         std::cout &lt;&lt; \"on constructor for obj \" &lt;&lt; this &lt;&lt; std::endl;     }     ~dummy_t() {         std::cout &lt;&lt; \"on destructor for obj \" &lt;&lt; this &lt;&lt; std::endl;     } };  void on_cleanup(dummy_t* dummy) {     std::cout &lt;&lt; \"on cleanup function for obj \" &lt;&lt; dummy &lt;&lt; std::endl; }  int main() {     std::cout &lt;&lt; \"before scope\" &lt;&lt; std::endl;     {         __attribute__((cleanup(on_cleanup))) dummy_t dummy;         std::cout &lt;&lt; \"inside scope\" &lt;&lt; std::endl;     }     std::cout &lt;&lt; \"after scope\" &lt;&lt; std::endl; }<\/code><\/pre>\n<pre><code>before scope on constructor for obj 0x7fff060964b8 inside scope on cleanup function for obj 0x7fff060964b8 on destructor for obj 0x7fff060964b8 after scope<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0432\u0438\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <code>on_cleanup<\/code>:<\/p>\n<pre><code>TranslationUnitDecl 0x205f068 &lt;&lt;invalid sloc>> &lt;invalid sloc> |-FunctionDecl 0x2ac5ac8 &lt;line:12:1, line:14:1> line:12:6 used on_cleanup 'void (dummy_t *)' | |-ParmVarDecl 0x2ac5a08 &lt;col:17, col:26> col:26 used dummy 'dummy_t *' | `-CompoundStmt 0x2ac8fc8 &lt;col:33, line:14:1> ...<\/code><\/pre>\n<p>\u0418 \u043d\u0430 variable declaration \u043a\u0440\u043e\u043c\u0435 \u043d\u0435\u044f\u0432\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0435\u0449\u0435 \u043f\u043e\u0432\u0435\u0448\u0435\u043d \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>CleanupAttr<\/code> \u0441\u043e \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434 <code>on_cleanup<\/code>:<\/p>\n<pre><code>    | |-DeclStmt 0x2acba70 &lt;line:19:9, col:59>     | | `-VarDecl 0x2acb7d0 &lt;col:9, col:54> col:54 dummy 'dummy_t' callinit destroyed     | |   |-CXXConstructExpr 0x2acba48 &lt;col:54> 'dummy_t' 'void ()'     | |   `-CleanupAttr 0x2acb838 &lt;col:24, col:42> Function 0x2ac5ac8 'on_cleanup' 'void (dummy_t *)'<\/code><\/pre>\n<p>\u0412\u044b\u0437\u043e\u0432 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437 AST \u0432 LLVM IR <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/00f8aecf6ef43fa0f4d2cdabeb1140bcfb477423\/clang\/lib\/CodeGen\/CGDecl.cpp#L2053-L2062\" rel=\"noopener noreferrer nofollow\">\u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435<\/a>. \u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 Clang \u0435\u0441\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 &#171;cleanup&#187; &#8212; \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u0435\u0449\u0435\u0439 \u043f\u043e \u0442\u0438\u043f\u0443 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 <code>CleanupAttr<\/code>. Cleanup-\u044b \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0432\u0438\u0434\u0435 LIFO-\u0441\u0442\u0435\u043a\u0430, \u0438 \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 scope, N \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 cleanup-\u043e\u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435.<\/p>\n<p>\u0414\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 <code>defer<\/code>-\u0430 \u044d\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434-\u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0443 \u0434\u043b\u044f <code>defer<\/code>-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e-\u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0443, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0441\u0435\u0442\u044c <code>CleanupAttr<\/code>.<\/p>\n<h4>\u041b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u044f\u0437\u044b\u043a\u0435 \u043d\u0435\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e, \u0438 \u043d\u0430 \u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u0434\u0438\u0437\u0430\u0439\u043d\u0435, \u0442\u043e \u0432\u0435\u043b\u0438\u043a \u0448\u0430\u043d\u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u0441\u0442\u044b\u043b\u0438 (\u0441\u043a\u0440\u044b\u0432\u0430\u044f \u0438\u0445 \u0437\u0430 \u044d\u0432\u0444\u0435\u043c\u0438\u0437\u043c\u0430\u043c\u0438) \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0438\u0434\u0438\u043e\u043c. \u041d\u0435 \u043e\u0431\u043e\u0448\u043b\u043e\u0441\u044c \u0431\u0435\u0437 \u043d\u0438\u0445 \u043f\u0440\u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 \u0421++11.<\/p>\n<p>\u0412 C++ \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0442 \u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0435\u0442\u043e\u0434, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043a\u0430\u043a \u0432 Python:<\/p>\n<pre><code class=\"python\">def sample():     def sum(a, b):         return a + b     print(sum(1, 2)) sample()<\/code><\/pre>\n<p>\u0425\u043e\u0442\u044f, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c class, struct, enum, union (\u044d\u0442\u043e \u0431\u043b\u0438\u0437\u043a\u043e\u0440\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438) \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0442\u0438 \u0432\u0435\u0437\u0434\u0435, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>\u0415\u0441\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/444524\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043b\u044f\u043c\u0431\u0434<\/a>, \u0433\u0434\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043e, \u043a\u0430\u043a \u043f\u0440\u043e\u0442\u043e-\u043b\u044f\u043c\u0431\u0434\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u0443\u0436\u0435 \u0432 C++03, \u0438 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0435 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0442\u043e\u0442 \u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434, \u0441\u043a\u0440\u044b\u0432\u0430\u044f \u0435\u0433\u043e \u0437\u0430 \u0447\u0435\u0440\u0442\u043e\u0433\u0430\u043c\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0442\u043e-\u043b\u044f\u043c\u0431\u0434\u0430 \u0434\u043b\u044f [](int x) { std::cout &lt;&lt; x &lt;&lt; std::endl; }<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;iostream> #include &lt;algorithm> #include &lt;vector>  struct PrintFunctor {     void operator()(int x) const {         std::cout &lt;&lt; x &lt;&lt; std::endl;     } };  int main() {     std::vector&lt;int> v;     v.push_back(1);     v.push_back(2);     std::for_each(v.begin(), v.end(), PrintFunctor());    }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 AST \u0434\u043b\u044f \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u043e\u0442 \u043f\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0433\u043b\u0430\u0437 \u043a\u043b\u0430\u0441\u0441 (\u043e\u043d \u0436\u0435 <code>CXXRecordDecl<\/code>):<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 AST \u0434\u043b\u044f \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;cstdio> int main() {     int gamma = 3;     const auto l = [&amp;](int alpha, int beta) { printf(\"%d\\n\", alpha + beta + gamma); };     l(1, 2); }<\/code><\/pre>\n<pre><code>`-FunctionDecl 0x24bbc38 &lt;lambda.cpp:2:1, line:6:1> line:2:5 main 'int ()'   `-CompoundStmt 0x24beb38 &lt;col:12, line:6:1>     |-DeclStmt 0x24bbd78 &lt;line:3:5, col:18>     | `-VarDecl 0x24bbcf0 &lt;col:5, col:17> col:9 used gamma 'int' cinit     |   `-IntegerLiteral 0x24bbd58 &lt;col:17> 'int' 3     |-DeclStmt 0x24be9c0 &lt;line:4:5, col:86>     | `-VarDecl 0x24bbdf0 &lt;col:5, col:85> col:16 used l 'const (lambda at lambda.cpp:4:20)':'const (lambda at lambda.cpp:4:20)' cinit     |   `-ExprWithCleanups 0x24be9a8 &lt;col:20, col:85> 'const (lambda at lambda.cpp:4:20)':'const (lambda at lambda.cpp:4:20)'     |     `-CXXConstructExpr 0x24be978 &lt;col:20, col:85> 'const (lambda at lambda.cpp:4:20)':'const (lambda at lambda.cpp:4:20)' 'void ((lambda at lambda.cpp:4:20) &amp;&amp;) noexcept' elidable     |       `-MaterializeTemporaryExpr 0x24be848 &lt;col:20, col:85> '(lambda at lambda.cpp:4:20)' xvalue     |         `-LambdaExpr 0x24be268 &lt;col:20, col:85> '(lambda at lambda.cpp:4:20)'     |           |-CXXRecordDecl 0x24bdc00 &lt;col:20> col:20 implicit class definition     |           | |-DefinitionData lambda pass_in_registers trivially_copyable can_const_default_init     |           | | |-DefaultConstructor     |           | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param     |           | | |-MoveConstructor exists simple trivial     |           | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param     |           | | |-MoveAssignment     |           | | `-Destructor simple irrelevant trivial     |           | |-CXXMethodDecl 0x24bdd40 &lt;col:43, col:85> col:20 used operator() 'void (int, int) const' inline     |           | | |-ParmVarDecl 0x24bbe70 &lt;col:24, col:28> col:28 used alpha 'int'     |           | | |-ParmVarDecl 0x24bbef0 &lt;col:35, col:39> col:39 used beta 'int'     |           | | `-CompoundStmt 0x24be098 &lt;col:45, col:85>     |           | |   `-CallExpr 0x24be050 &lt;col:47, col:82> 'int'     |           | |     |-ImplicitCastExpr 0x24be038 &lt;col:47> 'int (*)(const char *__restrict, ...)' &lt;FunctionToPointerDecay>     |           | |     | `-DeclRefExpr 0x24bdfc0 &lt;col:47> 'int (const char *__restrict, ...)' lvalue Function 0x249f198 'printf' 'int (const char *__restrict, ...)'     |           | |     |-ImplicitCastExpr 0x24be080 &lt;col:54> 'const char *' &lt;ArrayToPointerDecay>     |           | |     | `-StringLiteral 0x24bde88 &lt;col:54> 'const char [4]' lvalue \"%d\\n\"     |           | |     `-BinaryOperator 0x24bdfa0 &lt;col:62, col:77> 'int' '+'     |           | |       |-BinaryOperator 0x24bdf18 &lt;col:62, col:70> 'int' '+'     |           | |       | |-ImplicitCastExpr 0x24bdee8 &lt;col:62> 'int' &lt;LValueToRValue>     |           | |       | | `-DeclRefExpr 0x24bdea8 &lt;col:62> 'int' lvalue ParmVar 0x24bbe70 'alpha' 'int'     |           | |       | `-ImplicitCastExpr 0x24bdf00 &lt;col:70> 'int' &lt;LValueToRValue>     |           | |       |   `-DeclRefExpr 0x24bdec8 &lt;col:70> 'int' lvalue ParmVar 0x24bbef0 'beta' 'int'     |           | |       `-ImplicitCastExpr 0x24bdf88 &lt;col:77> 'int' &lt;LValueToRValue>     |           | |         `-DeclRefExpr 0x24bdf68 &lt;col:77> 'int' lvalue Var 0x24bbcf0 'gamma' 'int'     |           | |-FieldDecl 0x24be200 &lt;col:77> col:77 implicit referenced 'int &amp;'     |           | |-CXXDestructorDecl 0x24be2b0 &lt;col:20> col:20 implicit referenced ~ 'void () noexcept' inline default trivial     |           | |-CXXConstructorDecl 0x24be510 &lt;col:20> col:20 implicit constexpr  'void (const (lambda at lambda.cpp:4:20) &amp;)' inline default trivial noexcept-unevaluated 0x24be510     |           | | `-ParmVarDecl 0x24be628 &lt;col:20> col:20 'const (lambda at lambda.cpp:4:20) &amp;'     |           | `-CXXConstructorDecl 0x24be6c8 &lt;col:20> col:20 implicit used constexpr  'void ((lambda at lambda.cpp:4:20) &amp;&amp;) noexcept' inline default trivial     |           |   |-ParmVarDecl 0x24be7d8 &lt;col:20> col:20 used '(lambda at lambda.cpp:4:20) &amp;&amp;'     |           |   |-CXXCtorInitializer Field 0x24be200 '' 'int &amp;'     |           |   | `-MemberExpr 0x24be8f0 &lt;col:20> 'int' lvalue . 0x24be200     |           |   |   `-CXXStaticCastExpr 0x24be8c0 &lt;col:20> '(lambda at lambda.cpp:4:20)' xvalue static_cast&lt;class (lambda at lambda.cpp:4:20) &amp;&amp;> &lt;NoOp>     |           |   |     `-DeclRefExpr 0x24be890 &lt;col:20> '(lambda at lambda.cpp:4:20)' lvalue ParmVar 0x24be7d8 '' '(lambda at lambda.cpp:4:20) &amp;&amp;'     |           |   `-CompoundStmt 0x24be968 &lt;col:20>     |           |-DeclRefExpr 0x24be1c8 &lt;col:21> 'int' lvalue Var 0x24bbcf0 'gamma' 'int'     |           `-CompoundStmt 0x24be098 &lt;col:45, col:85>     |             `-CallExpr 0x24be050 &lt;col:47, col:82> 'int'     |               |-ImplicitCastExpr 0x24be038 &lt;col:47> 'int (*)(const char *__restrict, ...)' &lt;FunctionToPointerDecay>     |               | `-DeclRefExpr 0x24bdfc0 &lt;col:47> 'int (const char *__restrict, ...)' lvalue Function 0x249f198 'printf' 'int (const char *__restrict, ...)'     |               |-ImplicitCastExpr 0x24be080 &lt;col:54> 'const char *' &lt;ArrayToPointerDecay>     |               | `-StringLiteral 0x24bde88 &lt;col:54> 'const char [4]' lvalue \"%d\\n\"     |               `-BinaryOperator 0x24bdfa0 &lt;col:62, col:77> 'int' '+'     |                 |-BinaryOperator 0x24bdf18 &lt;col:62, col:70> 'int' '+'     |                 | |-ImplicitCastExpr 0x24bdee8 &lt;col:62> 'int' &lt;LValueToRValue>     |                 | | `-DeclRefExpr 0x24bdea8 &lt;col:62> 'int' lvalue ParmVar 0x24bbe70 'alpha' 'int'     |                 | `-ImplicitCastExpr 0x24bdf00 &lt;col:70> 'int' &lt;LValueToRValue>     |                 |   `-DeclRefExpr 0x24bdec8 &lt;col:70> 'int' lvalue ParmVar 0x24bbef0 'beta' 'int'     |                 `-ImplicitCastExpr 0x24bdf88 &lt;col:77> 'int' &lt;LValueToRValue>     |                   `-DeclRefExpr 0x24bdf68 &lt;col:77> 'int' lvalue Var 0x24bbcf0 'gamma' 'int'     `-CXXOperatorCallExpr 0x24beaf8 &lt;line:5:5, col:11> 'void':'void'       |-ImplicitCastExpr 0x24beab8 &lt;col:6, col:11> 'void (*)(int, int) const' &lt;FunctionToPointerDecay>       | `-DeclRefExpr 0x24bea38 &lt;col:6, col:11> 'void (int, int) const' lvalue CXXMethod 0x24bdd40 'operator()' 'void (int, int) const'       |-DeclRefExpr 0x24be9d8 &lt;col:5> 'const (lambda at lambda.cpp:4:20)':'const (lambda at lambda.cpp:4:20)' lvalue Var 0x24bbdf0 'l' 'const (lambda at lambda.cpp:4:20)':'const (lambda at lambda.cpp:4:20)'       |-IntegerLiteral 0x24be9f8 &lt;col:7> 'int' 1       `-IntegerLiteral 0x24bea18 &lt;col:10> 'int' 2<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0430 cppreference \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/lambda\" rel=\"noopener noreferrer nofollow\">lambda expression<\/a>, \u0433\u0434\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0431\u0438\u0442\u044c \u0441 \u0442\u043e\u043b\u043a\u0443 \u043d\u0435\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f:<\/p>\n<blockquote>\n<p>The lambda expression is a prvalue expression of <strong>unique unnamed non-union non-aggregate class<\/strong> type<\/p>\n<\/blockquote>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u0441\u0442\u044b\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0444\u0438\u0447\u0438, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u044b \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435 &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b\/\u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u043e \u0432\u043d\u044f\u0442\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043c\u043d\u043e\u0433\u0438\u0445 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u043b\u044f\u043c\u0431\u0434\u0430\u0445 \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0435\u0449\u0430\u0445 \u043a\u0430\u043a \u043e &#171;\u0447\u0435\u0440\u043d\u043e\u043c \u044f\u0449\u0438\u043a\u0435&#187;.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0434\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 <code>defer<\/code> \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0435\u043b \u0431\u044b \u043f\u0443\u0442\u044c \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439: \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 &#171;\u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e&#187; \u043a\u043b\u0430\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u043d\u0435\u043a\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (\u043a\u0430\u043a \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 cleanup-\u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c: \u043d\u043e\u0432\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0434\u043b\u044f AST).<\/p>\n<h4>Poor man&#8217;s defer<\/h4>\n<p><code>defer<\/code>-\u044b \u0432 production C++ \u043a\u043e\u0434\u0435 \u0432 \u0442\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c, \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">    struct dummy_t {         ~dummy_t() {             \/\/ \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u0434         }     } dummy;<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u043d\u043e\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0433\u043e: \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0435 \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u0430\u044f, \u0430 \u0438\u043c\u0435\u0435\u0442 \u0438\u043c\u044f, \u0438 \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442. \u042d\u0442\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c, \u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c \u043d\u0430 \u0441\u0442\u0435\u043a\u0435, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0431\u044b, \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u043d\u0435 \u0431\u044b\u043b\u043e.<\/p>\n<h4>\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/h4>\n<p>\u0412 \u0443\u0447\u0435\u0431\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <code>defer<\/code> \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 <code>struct<\/code> \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435<\/p>\n<pre><code class=\"cpp\">defer {     &lt;compound-expression> };<\/code><\/pre>\n<p>\u0411\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044e<\/p>\n<pre><code class=\"cpp\">struct &lt;MAGIC-STRUCT-NAME> {     ~&lt;MAGIC-STRUCT-NAME>() {         &lt;compound-expression>     } } &lt;MAGIC-OBJECT-NAME>;<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438\u0431\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u043a\u043e\u0443\u043f\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b <code>&lt;MAGIC-STRUCT-NAME><\/code> \u0438 <code>&lt;MAGIC-OBJECT-NAME><\/code> (\u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0441\u043a\u0438\u043c\u0438 \u0444\u043e\u043a\u0443\u0441\u0430\u043c\u0438 \u043a\u0430\u043a \u0434\u043b\u044f \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439), \u043b\u0438\u0431\u043e \u0434\u0430\u0442\u044c \u0438\u043c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <code>defer<\/code>-\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u0441\u043a\u043e\u0443\u043f\u0435.<\/p>\n<hr\/>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c defer<\/h2>\n<p><em>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u043c\u043c\u0438\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u043e <\/em><a href=\"https:\/\/github.com\/Izaron\/llvm-project\/commit\/2058d9fec62bc3abe3282c5f2f383d2e77282a7b\" rel=\"noopener noreferrer nofollow\"><em>\u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435<\/em><\/a><em>.<\/em><\/p>\n<h4>defer \u043a\u0430\u043a \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 struct<\/h4>\n<p>\u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 Clang \u0432 \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 (<code>ParseDecl.cpp<\/code>\/<code>ParseDeclCXX.cpp<\/code>) \u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (<code>ParseExpr.cpp<\/code>\/<code>ParseExprCXX.cpp<\/code>).<\/p>\n<p>&#171;\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e&#187; \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u043f\u0430\u0440\u0441\u0438\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u0431\u044b <code>defer<\/code> \u043d\u0430\u0447\u0430\u043b\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 (\u043f\u0440\u0438\u0447\u0451\u043c \u0437\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b), \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u0435-\u0433\u0434\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f:<\/p>\n<p>\u0412 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/fa82a3d016c9fb82c1b81834fa18cd4c797735a0\/clang\/lib\/Parse\/ParseTentative.cpp#L1389-L1392\" rel=\"noopener noreferrer nofollow\">Parser::isCXXDeclarationSpecifier<\/a> \u0438 \u0432 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/fa82a3d016c9fb82c1b81834fa18cd4c797735a0\/clang\/lib\/Parse\/ParseDecl.cpp#L4017-L4020\" rel=\"noopener noreferrer nofollow\">Parser::ParseDeclarationSpecifiers<\/a> \u0434\u043e\u0431\u0430\u0432\u0438\u043c <code>case tok::kw_defer:<\/code>.<\/p>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/fa82a3d016c9fb82c1b81834fa18cd4c797735a0\/clang\/lib\/Parse\/ParseDeclCXX.cpp#L1459\" rel=\"noopener noreferrer nofollow\">Parser::ParseClassSpecifier<\/a> \u0434\u0435\u043b\u0430\u0435\u043c <code>defer<\/code> \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c <code>struct<\/code>:<\/p>\n<pre><code class=\"cpp\">  const bool IsDefer = TagTokKind == tok::kw_defer;   if (TagTokKind == tok::kw_struct || IsDefer)     TagType = DeclSpec::TST_struct;<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u0434\u0435, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, <code>defer<\/code> \u043b\u0443\u0447\u0448\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c class-specifier (<code>DeclSpec::TST_struct<\/code>), \u043d\u043e \u0432 \u0443\u0447\u0435\u0431\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0434\u0438\u0437\u0430\u0439\u043d\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0430.<\/p>\n<p>\u0427\u0443\u0442\u044c \u043d\u0438\u0436\u0435 \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0438\u043c\u0435\u043d\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 (<code>IdentifierInfo *Name<\/code>). \u0417\u0430\u043f\u0440\u0435\u0442\u0438\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u0443 defer-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<pre><code>def err_named_defer_definition : Error&lt;\"defer structs should not have name\">;<\/code><\/pre>\n<pre><code class=\"cpp\">    \/\/ In case of \"defer\" it should not have name     if (IsDefer) {       if (Name != nullptr) {         Diag(NameLoc, diag::err_named_defer_definition);       }     }<\/code><\/pre>\n<p>\u0412\u044b\u0432\u043e\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u0440\u0438 \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430:<\/p>\n<pre><code>izaron@izaron:~\/check$ ~\/hack\/llvm-project\/build\/bin\/clang++ test.cpp  test.cpp:3:11: error: defer structs should not have name     defer defer_t { };           ^ 1 error generated.<\/code><\/pre>\n<h4>\u0418\u043c\u044f \u0434\u043b\u044f struct &#171;\u0438\u0437 \u0432\u043e\u0437\u0434\u0443\u0445\u0430&#187;<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u0437\u0430\u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0438\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u044e\u0437\u0435\u0440 \u043d\u0435 \u043f\u0438\u0441\u0430\u043b \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 (\u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0441\u0430\u043c\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 <code>struct { ... }<\/code> \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 <code>struct defer012345 { ... }<\/code>), \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0435\u044f\u0441\u043d\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>\u0412\u0441\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f (\u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0442.\u0434.) \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0438\u0437 \u0442\u043e\u043a\u0435\u043d\u043e\u0432-\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u0438 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u0438 \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u043d\u0435\u043e\u0442\u043a\u0443\u0434\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043d\u043e\u0432\u044b\u0439. \u041d\u043e \u0440\u0430\u043c\u043a\u0438 \u043d\u0435 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0451\u0441\u0442\u043a\u0438\u0435: \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/bc066e26c9926a33d91ba5635e48ef8486fc21c7\/clang\/include\/clang\/Basic\/IdentifierTable.h#L601\" rel=\"noopener noreferrer nofollow\">\u0437\u0430\u043a\u043e\u043d\u043d\u044b\u0439 \u0445\u0430\u043a<\/a> \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<pre><code class=\"cpp\">  \/\/ If this is a defer struct, create custom name for it   \/\/ \"defer {\" should imitate \"struct defer012345 {\"   if (IsDefer) {     Name = &amp;Context.Idents.getOwn(\"defer012345\");   }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u0438, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0430\u043c\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c defer-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 <code>SourceLocation<\/code> (\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f defer-\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0435), \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 <code>Y_DEFER<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<h4>\u0414\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0433\u043e struct<\/h4>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0443\u043d\u043a\u0442 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u043f\u0430\u0440\u0441\u044f\u0442\u0441\u044f \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0432 &#171;\u043e\u0431\u044b\u0447\u043d\u044b\u0445&#187; \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445, \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0434\u0435\u043b\u043e. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0434\u0432\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0430. \u0412 \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u0441\u044f <em>unqualified-id<\/em> (\u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c <code>~classname()<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0434\u043e \u043c\u0435\u0442\u043e\u0434\u0430 getDestructorName<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> #3 0x000056503ce39c00 clang::Parser::ParseUnqualifiedId(clang::CXXScopeSpec&amp;, clang::OpaquePtr&lt;clang::QualType>, bool, bool, bool, bool, bool, clang::SourceLocation*, clang::UnqualifiedId&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x5515c00)  #4 0x000056503cdfd200 clang::Parser::ParseDirectDeclarator(clang::Declarator&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54d9200)  #5 0x000056503cde36d0 clang::Parser::ParseDeclaratorInternal(clang::Declarator&amp;, void (clang::Parser::*)(clang::Declarator&amp;)) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54bf6d0)  #6 0x000056503ce0dd4d clang::Parser::ParseCXXMemberDeclaratorBeforeInitializer(clang::Declarator&amp;, clang::VirtSpecifiers&amp;, clang::ActionResult&lt;clang::Expr*, true>&amp;, clang::Parser::LateParsedAttrList&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54e9d4d)  #7 0x000056503ce10bd1 clang::Parser::ParseCXXClassMemberDeclaration(clang::AccessSpecifier, clang::ParsedAttributes&amp;, clang::Parser::ParsedTemplateInfo const&amp;, clang::ParsingDeclRAIIObject*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54ecbd1)  #8 0x000056503ce1381c clang::Parser::ParseCXXClassMemberDeclarationWithPragmas(clang::AccessSpecifier&amp;, clang::ParsedAttributesWithRange&amp;, clang::TypeSpecifierType, clang::Decl*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54ef81c)  #9 0x000056503ce13e2b clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, clang::SourceLocation, clang::ParsedAttributesWithRange&amp;, unsigned int, clang::Decl*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54efe2b) #10 0x000056503ce15fde clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, clang::SourceLocation, clang::DeclSpec&amp;, clang::Parser::ParsedTemplateInfo const&amp;, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext, clang::ParsedAttributesWithRange&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54f1fde)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f, \u0438 \u0441\u0430\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 Clang <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/bc066e26c9926a33d91ba5635e48ef8486fc21c7\/clang\/lib\/Sema\/SemaExprCXX.cpp#L141-L166\" rel=\"noopener noreferrer nofollow\">\u0436\u0430\u043b\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0437\u0430\u043f\u0443\u0442\u044b\u0432\u0430\u0435\u0442<\/a>.<\/p>\n<p>\u041a\u0430\u043a \u0431\u044b \u0442\u043e \u043d\u0438 \u0431\u044b\u043b\u043e, \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>unevaluated<\/em> (\u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0438\u0437 Clang), \u0438 \u0432\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u043b\u0430 \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u043b \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u0430\u043a \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u043f\u043e\u043b\u044f \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0430. \u0412\u0438\u0434\u0438\u043c\u043e, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u043e\u043d\u0438\u043c\u0430\u043b \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0438 \u043f\u043e\u043b\u044f\u043c \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0432\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0430 &#8212; \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0438 \u043f\u043e\u0434\u0441\u0443\u043d\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0442\u0435\u043b\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/bc066e26c9926a33d91ba5635e48ef8486fc21c7\/clang\/lib\/Sema\/SemaDeclCXX.cpp#L13527-L13593\" rel=\"noopener noreferrer nofollow\">Sema::DeclareImplicitDestructor<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u0440\u043e\u0438\u0442 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440. \u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 <code>Sema::DeclareUserDestructor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 user-defined \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430. \u041f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451 \u0442\u0430\u043c &#8212; \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430, \u043d\u043e \u043c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u0434\u0438\u0437\u0430\u0439\u043d\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 Sema::DeclareUserDestructor<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">CXXDestructorDecl *Sema::DeclareUserDestructor(CXXRecordDecl *ClassDecl) {   DeclaringSpecialMember DSM(*this, ClassDecl, CXXDestructor);   if (DSM.isAlreadyBeingDeclared())     return nullptr;    \/\/ Create the actual destructor declaration.   CanQualType ClassType     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));   SourceLocation ClassLoc = ClassDecl->getLocation();   DeclarationName Name     = Context.DeclarationNames.getCXXDestructorName(ClassType);   DeclarationNameInfo NameInfo(Name, ClassLoc);   CXXDestructorDecl *Destructor = CXXDestructorDecl::Create(       Context, ClassDecl, ClassLoc, NameInfo, QualType(), nullptr,       getCurFPFeatures().isFPConstrained(),       \/*isInline=*\/false,       \/*isImplicitlyDeclared=*\/false,       ConstexprSpecKind::Unspecified);   Destructor->setAccess(AS_public);    setupImplicitSpecialMemberType(Destructor, Context.VoidTy, None);    Destructor->setTrivial(false);    ++getASTContext().NumImplicitDestructorsDeclared;    Scope *S = getScopeForContext(ClassDecl);   CheckImplicitSpecialMemberDeclaration(S, Destructor);    \/\/ Introduce this destructor into its scope.   if (S)     PushOnScopeChains(Destructor, S, false);   ClassDecl->addDecl(Destructor);    return Destructor; }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0439\u0442\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/bc066e26c9926a33d91ba5635e48ef8486fc21c7\/clang\/lib\/Parse\/ParseDeclCXX.cpp#L3315-L3318\" rel=\"noopener noreferrer nofollow\">Parser::ParseCXXMemberSpecification<\/a>. \u0421\u0434\u0435\u043b\u0430\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>bool IsDefer<\/code>, \u0438 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/bc066e26c9926a33d91ba5635e48ef8486fc21c7\/clang\/lib\/Parse\/ParseDeclCXX.cpp#L3484\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/a> \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0451\u043c \u043e\u0431\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0432 Parser::ParseCXXMemberSpecification<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">  \/\/ defer structs should have only destructor definition instead of whole class body   if (TagDecl &amp;&amp; IsDefer) {     Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,                                             IsFinalSpelledSealed, IsAbstract,                                             TagDecl->getBeginLoc());      \/\/ First pass - register user-defined destructor     CXXRecordDecl* ClassDecl = dyn_cast&lt;CXXRecordDecl>(TagDecl);     CXXDestructorDecl* ClassDestructor = Actions.DeclareUserDestructor(ClassDecl);      \/\/ Second pass - add \"late parsed\" destructor body declaration     \/\/ I didn't found the method to get all tokens from \"{ ... }\", so I wrote the algo by hand     LexedMethod* LM = new LexedMethod(this, ClassDestructor);     getCurrentClass().LateParsedDeclarations.push_back(LM);     CachedTokens&amp; Toks = LM->Toks;      Toks.push_back(Tok);     unsigned tokenIndex = 1;     unsigned bracesNum = 1;     while (bracesNum > 0) {         const Token&amp; t = GetLookAheadToken(tokenIndex);         Toks.push_back(t);         if (t.is(tok::l_brace)) {             ++bracesNum;         } else if (t.is(tok::r_brace)) {             --bracesNum;         }         ++tokenIndex;     }      \/\/ Finish defer struct definition     ParsedAttributes attrs(AttrFactory);     Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,                                               TagDecl->getBeginLoc(),                                               TagDecl->getEndLoc(), attrs);      ParseLexedMethodDefs(getCurrentClass());      Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, SourceRange(TagDecl->getBeginLoc(), TagDecl->getEndLoc()));      \/\/ Leave the class scope.     ParsingDef.Pop();     ClassScope.Exit();      \/\/ Skip defer body     BalancedDelimiterTracker T(*this, tok::l_brace);     T.consumeOpen();     T.skipToEnd();      return;   }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0438 \u043f\u043e\u0434\u0441\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043a\u0435\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0431\u044b\u0442\u044c \u0435\u0433\u043e \u0442\u0435\u043b\u043e\u043c. \u042f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0434\u0430\u0441\u0442 \u043c\u043d\u0435 \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u043c\u0435\u0436\u0434\u0443 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u043a\u043e\u0431\u043a\u043e\u0439 <code>{<\/code> \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 <code>}<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0438\u0445 &#171;\u0440\u0443\u043a\u0430\u043c\u0438&#187;. \u0417\u0430\u0442\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u043f\u043e\u0441\u043b\u0435 <code>}<\/code>. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u0435\u0439 \u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0443 defer-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.<\/p>\n<p>\u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u0443\u0441\u043a\u0430 \u043a\u043e\u0434\u0430 \u043d\u0443\u0436\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0430\u0441\u0441 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f, \u0438 \u0441\u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0447\u0435\u043d\u044b \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u0430. \u0412 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 <strong>\u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e<\/strong> &#8212; \u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u0435\u043b\u0430\u044e \u0441\u043e\u043c\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c, \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c.<\/p>\n<p>\u0421\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0435\u0433\u043e:<\/p>\n<pre><code class=\"cpp\">#include &lt;cstdio>  int main() {     defer { printf(\"deferred 0\\n\"); } d0;      defer {         defer { printf(\"inner deferred\\n\"); } d;         printf(\"deferred 1\\n\");     } d1;      printf(\"hello!\\n\");     defer { printf(\"deferred 2\\n\"); } d2;     printf(\"world!\\n\"); }<\/code><\/pre>\n<pre><code>hello! world! deferred 2 deferred 1 inner deferred deferred 0<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0436\u0435 \u0437\u0430 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 LLVM IR, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 AST \u043e\u043d\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0435. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>~\/hack\/llvm-project\/build\/bin\/clang++ -emit-llvm -S test.cpp<\/code>, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c <code>test.ll<\/code>, \u0438 \u0432\u0438\u0434\u0438\u043c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b:<\/p>\n<pre><code>call void @\"_ZZ4mainEN3$_0D2Ev\"(%struct.anon.2* nonnull align 1 dereferenceable(1) %5) #4<\/code><\/pre>\n<p>\u0421 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Name_mangling#C++\" rel=\"noopener noreferrer nofollow\">name mangling<\/a>. \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043c <a href=\"https:\/\/godbolt.org\/z\/afsfzsfPa\" rel=\"noopener noreferrer nofollow\">demangle \u0438\u043c\u0451\u043d<\/a>:<\/p>\n<pre><code>main::$_0::~$_0() main::$_1::~$_1() main::$_2::~$_2() main::$_1::~$_1()::$_3::~$_3()<\/code><\/pre>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043b\u0438\u0441\u044c \u0438\u043c\u0435\u043d\u0430, \u043d\u043e \u043d\u0430 \u043f\u043e\u0437\u0434\u043d\u0435\u043c \u044d\u0442\u0430\u043f\u0435 &#8212; \u0432\u044b\u0437\u043e\u0432\u044b \u043f\u043e \u0442\u0438\u043f\u0443 <code>(*this).~$_0()<\/code> \u0438 <code>d0.~()<\/code> \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<h4>\u0410\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435-&#171;\u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0438&#187;<\/h4>\n<p>\u0412 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 <code>defer { ... } d;<\/code> \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>d<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u0431\u043e\u043b\u0432\u0430\u043d\u043a\u043e\u0439&#187;, \u043d\u0443\u0436\u043d\u043e\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0431\u0435\u0437 \u043d\u0435\u0435 defer-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c &#171;\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u043c\u0438&#187;.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0443, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>struct { ... };<\/code>\/<code>defer { ... };<\/code>, \u0442\u043e \u0432\u044b\u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0448\u0438\u0431\u043e\u043a, \u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 &#171;\u0431\u0438\u0442\u0430\u044f&#187; \u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>AST \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f struct{};<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>    `-DeclStmt 0x559d6c6c98d8 &lt;line:17:5, col:14>       |-CXXRecordDecl 0x559d6c6c96d0 &lt;col:5, col:13> col:5 struct definition       | `-DefinitionData is_anonymous pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init       |   |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr       |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param       |   |-MoveConstructor exists simple trivial needs_implicit       |   |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param       |   |-MoveAssignment exists simple trivial needs_implicit       |   `-Destructor simple irrelevant trivial needs_implicit       `-VarDecl 0x559d6c6c9858 &lt;col:5> col:5 implicit invalid '(anonymous struct at test.cpp:17:5)'<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u0435\u0431\u0430\u0436\u0438\u0432 Clang, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e &#171;\u0431\u0438\u0442\u0430\u044f&#187; \u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/fa82a3d016c9fb82c1b81834fa18cd4c797735a0\/clang\/lib\/Parse\/ParseDecl.cpp#L1804-L1811\" rel=\"noopener noreferrer nofollow\">Parser::ParseSimpleDeclaration<\/a>.<\/p>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u043a\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 <code>defer<\/code>-\u0430:<\/p>\n<pre><code class=\"cpp\">  const bool IsDefer = Tok.is(tok::kw_defer);<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043d\u0430 <code>tok::semi<\/code> (\u044d\u0442\u043e <code>;<\/code>) \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c defer-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c \u0438\u043c\u0435\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u043a\u043e\u0431\u043a\u0438 <code>}<\/code>:<\/p>\n<pre><code class=\"cpp\">  if (IsDefer &amp;&amp; !Tok.is(tok::semi)) {     Diag(Tok.getLocation(), diag::err_named_defer_variable);     return nullptr;   }<\/code><\/pre>\n<pre><code>def err_named_defer_variable : Error&lt;\"defer structs should not have variables\">;<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434 <code>ParsedFreeStandingDeclSpec<\/code> \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0434\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <code>BuildAnonymousStructOrUnion<\/code> \u043c\u044b \u043f\u0440\u043e\u043a\u0438\u043d\u0435\u043c \u0444\u043b\u0430\u0433 <code>IsDefer<\/code> \u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0434\u043b\u044f <code>defer<\/code> \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0430\u0441\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0430 &#8212; \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. (\u0427\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/Izaron\/llvm-project\/commit\/2058d9fec62bc3abe3282c5f2f383d2e77282a7b\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0435 \u043d\u0430 \u043a\u043e\u043c\u043c\u0438\u0442<\/a>).<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cpp\">#include &lt;iostream> using std::cout; using std::endl;  int main() {     defer { cout &lt;&lt; \"deferred 0\" &lt;&lt; endl; };      defer {         defer { cout &lt;&lt; \"inner deferred\" &lt;&lt; endl; };         cout &lt;&lt; \"deferred 1\" &lt;&lt; endl;     };      cout &lt;&lt; \"hello\" &lt;&lt; endl;     defer { cout &lt;&lt; \"deferred 2\" &lt;&lt; endl; };     cout &lt;&lt; \"world!\" &lt;&lt; endl; }<\/code><\/pre>\n<pre><code>hello world! deferred 2 deferred 1 inner deferred deferred 0<\/code><\/pre>\n<h4>\u0417\u0430\u0445\u0432\u0430\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430, \u043e\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 &#171;\u0432\u0438\u0434\u0435\u0442\u044c&#187; <em>\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435<\/em> \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0434\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u0412 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u044b\u0445 <code>defer<\/code>-\u0430\u0445 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0440\u0443\u043a\u0430\u043c\u0438 (\u0430 \u0432 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c) \u0442\u0430\u043a\u0438\u0435 \u0432\u0435\u0449\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0445\u0432\u0430\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;string>  int main() {     int alpha;     double beta;     std::string gamma;      class dummy_t {     public:         dummy_t(int&amp; alpha, double&amp; beta, std::string&amp; gamma)             : alpha{alpha}             , beta{beta}             , gamma{gamma}         {}          ~dummy_t() {             \/\/ some code...             \/\/ \"alpha\", \"beta\" and \"gamma\" are available         }      private:         int&amp; alpha;         double&amp; beta;         std::string&amp; gamma;     } dummy{alpha, beta, gamma}; }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 &#171;\u043d\u0430\u0448\u0443&#187; <code>defer<\/code>-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439, \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439-&#171;\u0431\u043e\u043b\u0432\u0430\u043d\u043a\u0438&#187;. \u042d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435\u0442\u0443. \u041d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c!<\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443?<\/h2>\n<p><em>\u041d\u0430 \u043f\u0440\u0430\u0432\u0430\u0445 \u0448\u0443\u0442\u043a\u0438:<\/em> \u0422\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u0440 \u0443\u0447\u0435\u0431\u043d\u044b\u0439, \u0438 <code>defer<\/code> \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u0435\u043d \u0432 C++, \u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0438\u043a\u0430\u043a =)<\/p>\n<p>\u0412\u043e\u043f\u0440\u043e\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b:<\/p>\n<h4>\u0421\u0442\u043e\u0440\u043e\u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/h4>\n<figure class=\"float bordered\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9af\/ea7\/953\/9afea79532297be665426d152de7f2ea.png\" width=\"250\" height=\"238\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9af\/ea7\/953\/9afea79532297be665426d152de7f2ea.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u0437 <code>defer<\/code>, \u0430 \u0441\u0434\u0435\u043b\u0430\u0442\u044c <code>DeferExpr<\/code> &#8212; \u043d\u043e\u0432\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f AST. \u0422\u043e\u0433\u0434\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437 AST \u0432 LLVM IR \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0435\u0446 \u043c\u0435\u0442\u043e\u0434\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>LLVM IR \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442 &#171;\u0431\u043b\u043e\u043a\u0430\u043c\u0438&#187; &#8212; \u044d\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u0440\u044f\u0434 \u0438\u0434\u0443\u0449\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c. \u0411\u043b\u043e\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043c\u0435\u0442\u043a\u0438 (label), \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043b\u0438\u0431\u043e <a href=\"https:\/\/llvm.org\/docs\/LangRef.html#terminator-instructions\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439<\/a>, \u043b\u0438\u0431\u043e \u043f\u0440\u044b\u0436\u043a\u043e\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<p>\u041f\u043e-\u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443 &#171;\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439&#187; \u0431\u043b\u043e\u043a (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430) \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d, \u043d\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e unwinding \u0441\u0442\u0435\u043a\u0430 \u043f\u043e exception-\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439, \u0430 &#171;\u043f\u0440\u043e\u0441\u0442\u043e&#187; \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 &#8212; \u0434\u0440\u0443\u0433\u0438\u043c. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f, \u0438 \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u0438\u0447\u0443\u0434\u044b.<\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u043f\u0443\u0442\u044c &#8212; \u0435\u0441\u043b\u0438 \u0432\u0438\u0434\u0438\u043c <code>defer<\/code>-\u0431\u043b\u043e\u043a, \u043c\u043e\u0436\u043d\u043e \u0432 AST-\u0434\u0435\u0440\u0435\u0432\u0435 &#171;\u043f\u0435\u0440\u0435\u0434\u0432\u0438\u043d\u0443\u0442\u044c&#187; \u044d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u0432 \u043a\u043e\u043d\u0435\u0446 \u0441\u043a\u043e\u0443\u043f\u0430, \u0433\u0434\u0435 \u043e\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d. \u041d\u043e \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0447\u0442\u043e <code>defer<\/code>-\u0431\u043b\u043e\u043a \u0431\u0443\u0434\u0435\u0442 &#171;\u0432\u0438\u0434\u0435\u0442\u044c&#187; \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e.<\/p>\n<h4>\u0421\u0442\u043e\u0440\u043e\u043d\u0430 \u044f\u0437\u044b\u043a\u0430<\/h4>\n<figure class=\"float bordered\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2f5\/45b\/b6c\/2f545bb6c16c3953d9c0f41b43cefc42.png\" width=\"190\" height=\"214\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2f5\/45b\/b6c\/2f545bb6c16c3953d9c0f41b43cefc42.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412 C++ \u043c\u043e\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u0441 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043e\u0447\u0435\u043d\u044c \u0434\u0430\u0432\u043d\u043e. \u0412 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u044f\u0437\u044b\u043a\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0435\u0431\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0432 \u0433\u043e\u0434 &#171;\u043a\u0438\u0434\u0430\u0442\u044c&#187; \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043e\u0432 \u043f\u043e \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0432 C++ \u0442\u0430\u043a \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u043e.<\/p>\n<p>\u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0432\u0432\u043e\u0434 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043b\u043e\u0445\u043e \u043f\u043e\u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435\/\u043c\u0435\u0442\u043e\u0434\u044b\/\u043a\u043b\u0430\u0441\u0441\u044b. \u0415\u0441\u0442\u044c \u043f\u0430\u0440\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u0443\u0440\u043e\u043d:<\/p>\n<ol>\n<li>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 <em>keyword<\/em>, \u0430 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/keyword\" rel=\"noopener noreferrer nofollow\"><em>identifier with special meaning<\/em><\/a>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043b\u043e\u0432\u0430 <code>final<\/code> \u0438 <code>override<\/code> \u043f\u0430\u0440\u0441\u044f\u0442\u0441\u044f Clang-\u043e\u043c \u043a\u0430\u043a \u0442\u043e\u043a\u0435\u043d-\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0430\u044e\u0442 \u043e\u0441\u043e\u0431\u044b\u0439 \u0441\u043c\u044b\u0441\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445, \u0430 \u0432 \u043f\u0440\u043e\u0447\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u043e\u0433\u0443\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0438\u043c\u0435\u043d\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/attributes\" rel=\"noopener noreferrer nofollow\">\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b<\/a>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>[[defer]] { ... }<\/code>. \u041c\u0438\u043d\u0443\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441 warning-\u043e\u043c, \u0430 \u043d\u0435 \u043f\u0430\u0434\u0430\u044e\u0442 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438: <code>warning: unknown attribute 'defer' ignored [-Wunknown-attributes]<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435-\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u0432\u044b\u0435 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b: <code>__attribute((defer))__ { ... }<\/code>. \u041d\u043e \u043c\u0438\u043d\u0443\u0441\u044b \u0442\u0430\u043a\u0438\u0435 \u0436\u0435, \u043a\u0430\u043a \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u043f\u0443\u043d\u043a\u0442\u0435. \u0418\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435 \u044d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c \u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<h2>\u041a\u043e\u043d\u0435\u0446<\/h2>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0432\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u043c\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439 \u043f\u0440\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/576052\/\"> https:\/\/habr.com\/ru\/articles\/576052\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f!<\/figcaption><\/figure>\n<p>C++ &#8212; \u043e\u0434\u0438\u043d \u0438\u0437 \u044f\u0437\u044b\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c &#171;\u043b\u0435\u0433\u0435\u043d\u0434\u0430\u0440\u043d\u044b\u043c&#187;. \u0415\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u0438\u0439, \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u043c \u0440\u0435\u0432\u043e\u043b\u044e\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u043d\u0435 \u0440\u0430\u0437, \u0430 <a href=\"http:\/\/open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2021\/n4892.pdf\" rel=\"noopener noreferrer nofollow\">\u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a<\/a> \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u0443\u0436\u0435 \u0440\u0430\u0437\u0440\u043e\u0441\u0441\u044f \u0434\u043e 1800+ \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043c\u0435\u043b\u043a\u043e\u0433\u043e \u0448\u0440\u0438\u0444\u0442\u0430.<\/p>\n<p>\u041d\u0430 C++ \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041d\u043e \u043d\u0435\u0440\u0435\u0434\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0434\u0435\u043b\u0430\u043b\u0438 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043c\u0435\u043d\u0435\u0435 \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u043c\u0438 \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c\u0438 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u0432 \u0441\u0430\u043c\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u041f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0438\u043c\u0435\u044e\u0442 \u043d\u0435\u0441\u043e\u0438\u0437\u043c\u0435\u0440\u0438\u043c\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435, \u0447\u0435\u043c \u043b\u044e\u0431\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0432 \u0443\u0447\u0435\u0431\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043b\u044f C++ \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 <code>defer<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0432 \u044f\u0437\u044b\u043a\u0430\u0445 Go \u0438 Swift. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0430\u0432\u043a\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 Clang.<\/p>\n<figure class=\"\"><figcaption>\u041c\u0430\u0441\u043a\u043e\u0442 LLVM \u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u043b\u0430\u043f\u0430\u0445 C++<\/figcaption><\/figure>\n<h2>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b defer<\/h2>\n<p>\u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 Go \u0438 Swift, \u0435\u0441\u0442\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e defer. \u0412 Go \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 (exceptions), \u043d\u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0434\u0438\u043e\u043c\u0430 \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 &#8212; \u043f\u0440\u044f\u043c\u043e\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u044f\u0437\u044b\u043a\u0443 \u0432\u044b\u0437\u0432\u0430\u0442\u044c cleanup-\u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0432\u044b\u0445\u043e\u0434\u0443 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<pre><code class=\"go\">func write(fileName string, text string) error {     file, err := os.Create(fileName)     if err != nil {         return err     }     defer file.Close()     \/\/ ... \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e return-\u043e\u0432, file.Close() \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, C++ \u043d\u0435 \u043d\u0443\u0436\u0435\u043d <code>defer<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0438\u0434\u0438\u043e\u043c\u0430 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/raii\" rel=\"noopener noreferrer nofollow\">RAII<\/a>. \u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u043c C++-\u043a\u043e\u0434\u0435 \u0431\u044b\u043b \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043d\u0435\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 <code>os.Create<\/code> \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435, \u0430 <code>file.Close()<\/code> \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435. \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>defer<\/code> \u0432 \u044d\u0442\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u0441\u0451\u0442 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440.<\/p>\n<hr\/>\n<h2>defer \u0432 open-source \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445<\/h2>\n<p><code>defer<\/code> \u0441 \u0440\u0430\u0437\u043d\u044b\u043c \u0443\u0441\u043f\u0435\u0445\u043e\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 &#171;\u0440\u0443\u043a\u0430\u043c\u0438&#187;.<\/p>\n<p><a href=\"https:\/\/www.boost.org\/doc\/libs\/1_77_0\/libs\/scope_exit\/doc\/html\/index.html\" rel=\"noopener noreferrer nofollow\">Boost.ScopeExit<\/a> &#8212; \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 <code>defer<\/code>-\u0430. \u041e\u043d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043d\u0430 C++11 \u0432\u043f\u0435\u0440\u0435\u043c\u0435\u0448\u043a\u0443 \u0441 C++03, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0438\u0437\u043b\u0438\u0448\u043d\u0435 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u0430 \u0438 \u043c\u0430\u043b\u043e \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0438.<\/p>\n<p>\u0425\u043e\u0442\u044f Boost &#8212; \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u0435\u0433\u043e \u043a\u0443\u0441\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0430\u0436\u0443\u0440\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0412 Boost <a href=\"https:\/\/www.boost.org\/doc\/libs\/\" rel=\"noopener noreferrer nofollow\">167<\/a> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430. \u041c\u043d\u043e\u0433\u0438\u0435 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043b\u0438\u0431\u043e \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0441 ~2006 \u0433\u043e\u0434\u0430, \u043b\u0438\u0431\u043e \u0441\u0442\u0430\u043b\u0438 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442, \u043b\u0438\u0431\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0442 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443, \u043b\u0438\u0431\u043e \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0432\u043d\u0435 Boost \u0441 \u043b\u0443\u0447\u0448\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c.<\/p>\n<p><a href=\"https:\/\/github.com\/catboost\/catboost\" rel=\"noopener noreferrer nofollow\">CatBoost<\/a> &#8212; \u0432 \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0434\u043b\u044f \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 <a href=\"https:\/\/github.com\/catboost\/catboost\/blob\/master\/util\/generic\/scope.h#L65\" rel=\"noopener noreferrer nofollow\">Y_DEFER<\/a>.<\/p>\n<p>\u041e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e <code>defer<\/code>-\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043a\u0440\u044b\u0442\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u0434. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0445\u0438\u0442\u0440\u043e\u0443\u043c\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">#define Y_SCOPE_EXIT(...) const auto Y_GENERATE_UNIQUE_ID(scopeGuard) Y_DECLARE_UNUSED = ::NPrivate::TMakeGuardHelper{} | [__VA_ARGS__]() mutable -> void #define Y_DEFER Y_SCOPE_EXIT(&amp;)<\/code><\/pre>\n<p><code>Y_GENERATE_UNIQUE_ID(scopeGuard)<\/code> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<p><code>Y_DECLARE_UNUSED<\/code> \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p><code>[__VA_ARGS__]() mutable -> void<\/code> &#8212; \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u043b\u044f \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u0443\u0434\u0430 \u0437\u0430\u043f\u0438\u0448\u0435\u0442\u0441\u044f <code>&amp;<\/code>. <code>mutable<\/code> \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. <code>-> void<\/code> \u044d\u0442\u043e trailing return type, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043b\u044f\u043c\u0431\u0434\u044b.<\/p>\n<p><code>TMakeGuardHelper<\/code> \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0442\u0430\u043a, \u0447\u0442\u043e \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c <code>TMakeGuardHelper{} | &lt;\u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435><\/code>.<\/p>\n<p>\u041c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>defer<\/code>-\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u0435\u0441\u0442\u0430 \u0435\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f &#8212; \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0442\u043e\u0433\u043e scope, \u0433\u0434\u0435 \u043e\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d, \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435:<\/p>\n<pre><code class=\"cpp\">{     A a;     B b;     Y_DEFER { &lt;body> };     C c;     D d;      \/\/ \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u0434...      \/\/ \u0432\u044b\u0437\u043e\u0432 \u043f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 d.~D(), c.~C(), { &lt;body> }, b.~B(), a.~A() }<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u043b\u0430 <code>defer<\/code> \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0440\u043e\u0441\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e <a href=\"https:\/\/habr.com\/ru\/post\/433944\/\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u0443\u0435\u0442 std::terminate<\/a>.<\/p>\n<hr\/>\n<h2>Clang \u0438 LLVM<\/h2>\n<p>\u041f\u0440\u043e \u0441\u0430\u043c\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Clang \u0438 LLVM \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0443\u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439. \u041d\u0430 \u0445\u0430\u0431\u0440\u0435 \u044f \u0431\u044b \u043f\u043e\u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b <a href=\"https:\/\/habr.com\/ru\/company\/huawei\/blog\/511854\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e<\/a>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0445 \u043a\u0440\u0430\u0442\u043a\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0438 \u043e\u0431\u0449\u0443\u044e \u0441\u0445\u0435\u043c\u0443.<\/p>\n<p>\u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c \u043c\u0438\u0440\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0441 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0431\u0435\u0434\u0438\u043b\u0438. Clang \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f\u0445 &#8212; Yandex, Apple, Google (\u0432 \u043d\u0451\u043c 400-450\u043c\u043b\u043d \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430 \u043d\u0430 C++) \u0438 \u0442.\u0434.; \u0442\u0430\u043a \u0438 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 &#8212; FreeBSD, OpenBSD, Android, Chrome, Firefox, LibreOffice \u0438 \u0442.\u0434.<\/p>\n<p>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0434\u0438\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430. \u0410\u043d\u0430\u0442\u043e\u043c\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430 \u0438 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:<\/p>\n<ul>\n<li>\n<p><strong>Front-end<\/strong>: \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a \u0438\u0437 C\/C++\/Ada\/Rust\/Haskell\/&#8230; \u0432 <a href=\"https:\/\/llvm.org\/docs\/LangRef.html\" rel=\"noopener noreferrer nofollow\">LLVM IR<\/a> &#8212; \u043e\u0441\u043e\u0431\u043e\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c \u0434\u043b\u044f C-like \u044f\u0437\u044b\u043a\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>Clang<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Middle-end<\/strong>: LLVM IR \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n<\/li>\n<li>\n<p><strong>Back-end<\/strong>: LLVM IR \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u043e\u0434 \u043d\u0443\u0436\u043d\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 &#8212; x86\/Arm\/PowerPC\/&#8230;<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u043e\u0434 <a href=\"https:\/\/llvm.org\/docs\/tutorial\/MyFirstLanguageFrontend\/index.html\" rel=\"noopener noreferrer nofollow\">1000 \u0441\u0442\u0440\u043e\u043a<\/a> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u044e \u043c\u043e\u0449\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 LLVM &#8212; \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c lex\/yacc &#8212; \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b.<\/p>\n<p>\u041d\u0430 \u043c\u0435\u043d\u0435\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 <strong>Clang<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044f \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 &#171;\u043c\u0438\u043a\u0440\u043e&#187;-\u0448\u0430\u0433\u0438):<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9B%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7\" rel=\"noopener noreferrer nofollow\">\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437<\/a>: \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u0442\u043e\u043a\u0435\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>[]() { return 13 + 37; }<\/code> \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 <code>(l_square) (r_square) (l_paren) (r_paren) (l_brace) (return) (numeric_constant:13) (plus) (numeric_constant:37) (semi) (r_brace)<\/code>.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A1%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7\" rel=\"noopener noreferrer nofollow\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437<\/a>: \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 AST (Abstract Syntax Tree), \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u0432 \u0432\u0438\u0434 <code>(lambda-expr (body (return-expr (plus-expr (number 13) (number 37)))))<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f: \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 LLVM IR \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u043c\u0443 AST.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, &#171;\u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438&#187; \u043e\u0447\u0435\u043d\u044c \u0447\u0435\u0442\u043a\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 Clang \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0433\u0438\u0433\u0430\u043d\u0442\u0441\u043a\u0438\u0435. \u041d\u0430 \u043c\u043e\u0439 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0440\u0430\u0441\u043f\u0443\u0445\u0448\u0438\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441 \u0444\u0430\u043a\u0442\u043e\u043c, \u0447\u0442\u043e C++ &#8212; \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0439 \u044f\u0437\u044b\u043a.<\/p>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Compilers:_Principles,_Techniques,_and_Tools\" rel=\"noopener noreferrer nofollow\">DragonBook<\/a>. Clang \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0435\u0433\u043e, \u043d\u043e C++ \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043e\u043d\u0438\u0442\u044c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 ad-hoc \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 \u0438 \u043a\u043e\u0441\u0442\u044b\u043b\u044f\u043c\u0438.<\/p>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438 \u0441\u0431\u043e\u0440\u043a\u0430 Clang<\/h2>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 <a href=\"https:\/\/clang.llvm.org\/get_started.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0442\u0430\u043a\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code class=\"bash\">git clone https:\/\/github.com\/llvm\/llvm-project.git cd llvm-project &amp;&amp; mkdir build &amp;&amp; cd build cmake -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release ..\/llvm make -j 4<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c <code>make clang -j 4<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0438\u043b\u0434 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e. \u042f \u0432\u044b\u0431\u0440\u0430\u043b release-\u0441\u0431\u043e\u0440\u043a\u0443 <code>-DCMAKE_BUILD_TYPE=Release<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a debug-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u043e\u043b\u044c\u043a\u043e, \u0447\u0442\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a clang \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0435 \u0441\u043b\u0438\u043d\u043a\u0443\u0435\u0442\u0441\u044f (\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043b\u0438\u043d\u043a\u0435\u0440\u0430 \u0443\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e Out-Of-Memory \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0436\u0438\u0440\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043a\u0438), \u043d\u043e \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0432\u0435\u0437\u0442\u0438 \u0441 \u044d\u0442\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f \u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435\u043c debug-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <a href=\"https:\/\/clang.llvm.org\/hacking.html#debugging\" rel=\"noopener noreferrer nofollow\">\u043c\u0435\u0442\u043e\u0434<\/a> <code>dump()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432 stderr. \u0422\u0430\u043a\u0436\u0435, \u0435\u0441\u043b\u0438 \u0441\u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0434\u0435\u043d\u0438\u0435 clang-\u0430, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p>Clang \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0431\u043e\u0440\u043a\u0438 CMake, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 IDE, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0435\u0433\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c.<\/p>\n<hr\/>\n<h2>\u041d\u043e\u0432\u043e\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e defer<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u043e <code>defer<\/code>, Clang \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442 \u0435\u0433\u043e \u043a\u0430\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (\u0442\u043e\u043a\u0435\u043d \u0432\u0438\u0434\u0430 identifier) \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0432 expression), \u0438 \u043a\u043e\u0434 \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0431\u044b\u043b \u0440\u0430\u043d\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d (\u0432 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c declaration).<\/p>\n<pre><code class=\"cpp\">int main() {     defer; }<\/code><\/pre>\n<pre><code>file.cpp:2:5: error: use of undeclared identifier 'defer'     defer;     ^ 1 error generated.<\/code><\/pre>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/main\/clang\/include\/clang\/Basic\/TokenKinds.def\" rel=\"noopener noreferrer nofollow\">clang\/include\/clang\/Basic\/TokenKinds.def<\/a>. \u041f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u0443\u0441\u043a\u0438 Clang-\u0430 \u043c\u043e\u0433\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0438\u043d\u043a\u043b\u044e\u0434\u0438\u0442\u044c \u0438\u0445 \u043a \u0441\u0435\u0431\u0435 \u0432 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043a\u043e\u0434\u0430: <code>#include \"clang\/Basic\/TokenKinds.def\"<\/code>.<\/p>\n<p>Clang \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u0432 \u044f\u0437\u044b\u043a\u043e\u0432 C, C++, Objective-C; \u0434\u043b\u044f \u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0435\u043a \u043d\u0430\u0434 \u044f\u0437\u044b\u043a\u0430\u043c\u0438 OpenMP, OpenCL, CUDA \u0438 \u043f\u0440.; \u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043a\u043e\u0441\u0442\u044b\u043b\u0435\u0439 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0432 \u044f\u0437\u044b\u043a \u043e\u0442 Microsoft, GNU, \u0441\u0430\u043c\u043e\u0433\u043e Clang \u0438 \u043f\u0440.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 Clang \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u0439. \u0415\u0441\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u044d\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043e \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438: <code>ParseExprCXX.cpp<\/code>, <code>ParseOpenMP.cpp<\/code>. \u0421\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 &#8212; \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f \u0432\u0441\u0435\u0445. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0443\u0434\u0430 \u043d\u043e\u0432\u043e\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f C++:<\/p>\n<pre><code class=\"cpp\">KEYWORD(defer                       , KEYCXX)<\/code><\/pre>\n<p>\u0418 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c Clang. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u043a\u0441\u0435\u0440 (\u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440) \u043d\u0430\u0443\u0447\u0438\u043b\u0441\u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u0441\u0440\u0430\u0437\u0443. \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/microsoft\/blog\/458242\/\" rel=\"noopener noreferrer nofollow\">spaceship operator<\/a>, \u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u043b\u0435\u043a\u0441\u0435\u0440: <a href=\"https:\/\/github.com\/llvm\/llvm-project\/commit\/edbf5972a4c912d9e03b6c33ef73872603ca0522#diff-e0caa2ace07c5d0a47aa3d905d2dafe4b14f5bdbfcbbffd40da6aa4c62fee0a9\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u043c\u043c\u0438\u0442 \u0441\u043e spaceship<\/a>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c Clang \u043d\u0435 \u0434\u0443\u043c\u0430\u0435\u0442, \u0447\u0442\u043e <code>defer<\/code> \u044d\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e identifier, \u043d\u043e \u0438 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f:<\/p>\n<pre><code>file.cpp:2:5: error: expected expression     defer;     ^ 1 error generated.<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435\u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u0440\u0441\u0435\u0440\u0435 (\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435) <a href=\"https:\/\/github.com\/llvm\/llvm-project\/blob\/00f8aecf6ef43fa0f4d2cdabeb1140bcfb477423\/clang\/lib\/Parse\/ParseExpr.cpp#L1761-L1763\" rel=\"noopener noreferrer nofollow\">\u0432 Parser::ParseCastExpression<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u043a \u044d\u0442\u043e\u043c\u0443 \u043c\u0435\u0441\u0442\u0443<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> #3 0x000056335ad3d395 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&amp;, clang::Parser::TypeCastState, bool, bool*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54f8395)  #4 0x000056335ad3ff2e clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54faf2e)  #5 0x000056335ad4011d clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54fb11d)  #6 0x000056335ad448ed clang::Parser::ParseExpression(clang::Parser::TypeCastState) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x54ff8ed)  #7 0x000056335adbac80 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x5575c80)  #8 0x000056335adaec0e clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector&lt;clang::Stmt*, 32u>&amp;, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributesWithRange&amp;) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x5569c0e)  #9 0x000056335adafeca clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector&lt;clang::Stmt*, 32u>&amp;, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (\/home\/izaron\/hack\/llvm-project\/build\/bin\/clang-14+0x556aeca) #10 0x000056335adb0cf1 clang::Parser::ParseCompoundStatementBody(bool)<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-388405","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/388405","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=388405"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/388405\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=388405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=388405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=388405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}