C ++ روسيا: كيف كان الحال

إذا قلت في بداية المسرحية أن كود C ++ معلقة على الحائط ، في النهاية يجب عليك إطلاق النار عليك في القدم.

Bjarne Stroustrup

من 31 أكتوبر إلى 1 نوفمبر ، استضافت سان بطرسبرغ مؤتمر C ++ Russia Piter ، وهو واحد من أكبر مؤتمرات البرمجة في روسيا التي نظمتها مجموعة JUG Ru. من بين المتحدثين المدعوين هم أعضاء في لجنة توحيد C ++ ، ومتحدثون لدى CppCon ، ومؤلفي كتب O'Reilly ، وأيضًا مشرفي مشاريع مثل LLVM و libc ++ و Boost. يهدف المؤتمر إلى مطوري C ++ ذوي الخبرة الذين يرغبون في تعميق خبراتهم وتبادل الخبرات في مجال التواصل المباشر. وتقدم للطلاب وطلاب الدراسات العليا وأساتذة الجامعة خصومات ممتعة للغاية.

يمكن زيارة نسخة موسكو من المؤتمر بالفعل في أبريل من العام المقبل ، ولكن في الوقت الحالي سيخبرك طلابنا بالأشياء المثيرة للاهتمام التي تعلموها في الحدث الأخير.



صورة من ألبوم المؤتمر

عنا


عمل طالبان من المدرسة العليا للاقتصاد - سان بطرسبرغ ، على هذا المنصب:

  • ليزا فاسيلينكو طالبة جامعية في السنة الرابعة تدرس اتجاه "لغات البرمجة" كجزء من برنامج "الرياضيات التطبيقية وعلوم الكمبيوتر". تعرف على لغة C ++ في السنة الأولى من الجامعة ، اكتسبت بعد ذلك خبرة في العمل معها في التدريب الداخلي في الصناعة. تركت شغف لغات البرمجة بشكل عام والبرمجة الوظيفية بصماتها بشكل خاص على اختيار التقارير في المؤتمر.
  • دانيا سميرنوف طالبة في السنة الأولى من برنامج الماجستير "برمجة البيانات وتحليلها". بينما كان لا يزال في المدرسة ، كتب مشاكل الأولمبياد في لغة C ++ ، ثم حدث بطريقة ما أن اللغة ظهرت باستمرار في الأنشطة التعليمية ونتيجة لذلك أصبحت اللغة الرئيسية في العمل. قررت المشاركة في المؤتمر من أجل تحسين معرفتي ، وكذلك التعرف على الفرص الجديدة.

في النشرة الإخبارية ، غالباً ما يتبادل قادة أعضاء هيئة التدريس معلومات عن الأحداث التعليمية المتعلقة بتخصصنا. في سبتمبر ، شاهدنا معلومات حول C ++ Russia وقررت التسجيل كمستمعين. هذه هي تجربتنا الأولى في المشاركة في مثل هذه المؤتمرات.

هيكل المؤتمر


  • تقارير


على مدار يومين ، قرأ الخبراء 30 تقريرًا يسلطون الضوء على العديد من الموضوعات الساخنة: التطبيقات الذكية لميزات اللغة لحل المشكلات المطبقة ، تحديثات اللغة القادمة بسبب المعيار الجديد ، الحلول الوسط في تصميم C ++ والاحتياطات عند العمل مع عواقبها ، أمثلة على بنية المشروع المثيرة للاهتمام ، وكذلك بعض أجزاء محرك البنية التحتية للغات. في الوقت نفسه ، تم إجراء 3 عروض ، معظمها مرتين باللغة الروسية وواحدة باللغة الإنجليزية.

  • مناطق المناقشة


بعد الخطاب ، تم نقل جميع الأسئلة التي لم تتم الإجابة عليها والمناقشات غير المكتملة إلى مناطق اتصال مخصصة بشكل خاص مع مكبرات صوت مزودة بلوحات علامات. طريقة جيدة لتمرير الاستراحة بين العروض لمحادثة ممتعة.

  • محادثات البرق والمناقشات غير الرسمية


إذا كنت ترغب في تقديم تقرير قصير ، فيمكنك الاشتراك في برنامج Lightning Talk المسائي على السبورة والحصول على خمس دقائق من الوقت للتحدث عن أي شيء حول موضوع المؤتمر. على سبيل المثال ، مقدمة سريعة للمطهرات لـ C ++ (التي اتضح أنها جديدة بالنسبة للبعض) أو قصة عن خلل في توليد الجيب الجيبي الذي لا يمكنك سماعه إلا دون رؤيته.

شكل آخر هو حلقة النقاش "مع لجنة الروح". على المسرح ، يوجد بعض أعضاء لجنة التقييس ، على جهاز العرض - الموقد (رسميًا - لخلق جو مليء بالحيوية ، لكن السبب "لأن كل شيء على النار" يبدو أكثر تسلية) ، أسئلة - حول الرؤية المعيارية والعامة لـ C ++ ، دون مناقشات فنية وجامعات. اتضح أن الأشخاص الأحياء يشاركون أيضًا في اللجنة ، والذين قد لا يكونون متأكدين تمامًا من شيء ما أو قد لا يعرفون شيئًا ما.

بالنسبة لعشاق holivar ، بقي الحدث الثالث - جلسة BOF "Go ضد C ++". نحن نأخذ عاشق Go ، عاشق C ++ ، قبل بدء الجلسة ، يعدون 100500 شريحة حول هذا الموضوع معًا (مثل المشكلات في الحزم في C ++ أو عدم وجود الأدوية في Go) ، ثم يناقشون بشكل حيوي فيما بينهم وبين الجمهور ، ويحاول الجمهور فهم نقطتي العرض في وقت واحد . إذا لم يبدأ holivar في العمل ، يتدخل المشرف ويصالح الأطراف. هذا التنسيق يسبب الإدمان: بعد بضع ساعات من البدء ، تم إكمال نصف الشرائح فقط. كان لا بد من تسريع النهاية.

  • شركاء تقف


تم تمثيل شركاء المؤتمر في القاعات - فقد تحدثوا عن المشاريع الحالية في المدرجات ، وعرضوا التدريب الداخلي والتوظيف ، وعقدوا مسابقات ومسابقات صغيرة ، ولعبوا أيضًا جوائز رائعة. ومع ذلك ، فقد عرضت بعض الشركات الدخول في المراحل الأولية من المقابلات ، والتي قد تكون مفيدة لأولئك الذين جاءوا ليس فقط للاستماع إلى التقارير.

التفاصيل الفنية للتقارير


لقد استمعنا إلى التقارير في اليومين. في بعض الأحيان كان من الصعب اختيار تقرير واحد من أولئك الذين يعملون بالتوازي - وافقنا على تبادل وتبادل المعرفة المكتسبة خلال فترات الاستراحة. ومع ذلك ، يبدو أن الكثير قد ضاع. هنا نود التحدث عن محتوى بعض التقارير التي تبدو لنا الأكثر إثارة للاهتمام

استثناءات في C ++ عبر منظور تحسينات برنامج التحويل البرمجي ، رومان روسييف




شريحة العرض التقديمي

كما يوحي الاسم ، نظر رومان في العمل مع استثناءات باستخدام LLVM كمثال. في الوقت نفسه ، بالنسبة لأولئك الذين لا يستخدمون Clang في عملهم ، لا يزال بإمكان التقرير إعطاء فكرة عن كيفية تحسين الكود. وذلك لأن مطوري برامج التحويل البرمجي والمكتبات القياسية المقابلة يتصلون مع بعضهم البعض وقد تتزامن العديد من الحلول الناجحة.

لذلك ، للتعامل مع الاستثناء ، تحتاج إلى القيام بالكثير من الإجراءات: استدعاء رمز المعالجة (إن وجد) أو تحرير الموارد على المستوى الحالي واسترخاء المكدس أعلى. كل هذا يؤدي إلى حقيقة أن المترجم يضيف تعليمات إضافية لإمكانية إجراء المكالمات. لذلك ، في حالة عدم حدوث استثناء في الواقع ، سيبدأ البرنامج في تنفيذ الإجراءات غير الضرورية. من أجل تقليل التكاليف العامة بطريقة أو بأخرى ، تمتلك LLVM العديد من الاستدلال لتحديد المواقف التي لا تحتاج فيها إلى إضافة رمز معالجة استثناء أو يمكنك تقليل عدد الإرشادات "غير الضرورية".

يأخذ المتحدث في الاعتبار نحو عشرة منهم ويظهر كلا الحالتين حيث تساعد في تسريع تنفيذ البرنامج ، وتلك التي لا تكون هذه الطرق قابلة للتطبيق.

وهكذا ، يقود رومان روسييف الجمهور إلى استنتاج مفاده أن الشفرة التي تحتوي على عمل مع استثناءات لا يمكن تنفيذها بأي حال من الأحوال دون الصفر ، وتقدم النصائح التالية:

  • عند تطوير المكتبات ، يجب أن تتخلى عن الاستثناءات من حيث المبدأ ؛
  • إذا كنت لا تزال بحاجة إلى استثناءات ، فحينما يكون ذلك ممكنًا ، من الجدير إضافة معدّلات noexcept (و const) حتى يتمكن المحول البرمجي من تحسين أكبر قدر ممكن.

بشكل عام ، كرر المتحدث وجهة النظر القائلة بأن الاستثناءات أفضل استخدامًا إلى الحد الأدنى ، أو حتى التخلي عنها.

تتوفر شرائح التقرير على العنوان التالي: ["استثناءات C ++ من خلال المنشور الخاص بـ LLVM Compiler Optimization"]

مولدات ، coroutines وغيرها من حلاوة تفكك الدماغ ، عدي شافيت



شريحة العرض التقديمي

تم تذكر أحد التقارير العديدة لهذا المؤتمر المكرس لابتكارات C ++ 20 ليس فقط من خلال العرض التقديمي المقدم بشكل ملون ، ولكن أيضًا من خلال التحديد الواضح للمشاكل الموجودة في منطق معالجة المجموعات (من أجل حلقة رد الاتصال).

يسلط Adi Shavit الضوء على ما يلي: تمر الطرق المتاحة حاليًا عبر المجموعة بأكملها ولا تتيح الوصول إلى بعض الحالات الوسيطة الداخلية (أو تقدم في حالة عمليات الاسترجاعات ، ولكن مع الكثير من الآثار الجانبية غير السارة ، مثل نفس Callback Hell). يبدو أن هناك متكررين ، لكن ليس كل شيء سلسًا معهم: لا توجد نقاط دخول وخروج مشتركة (ابدأ → نهاية مقابل rbegin → rend وما إلى ذلك) ، فمن غير الواضح كم سنقوم بالتكرار على الإطلاق؟ بدءًا من C ++ 20 ، يتم حل هذه المشكلات!

الخيار الأول: يتراوح. نظرًا للالتفاف الموجود أعلى التكرارات ، نحصل على واجهة مشتركة لبداية ونهاية التكرار ، وكذلك إمكانية التركيب. كل هذا يجعل من السهل بناء خطوط أنابيب معالجة البيانات كاملة. ولكن ليس كل شيء سلسًا: جزء من منطق العمليات الحسابية هو داخل تطبيق مكرر معين ، مما قد يعقد التعليمات البرمجية للتصور وتصحيح الأخطاء.


شريحة العرض التقديمي

حسنًا ، في هذه الحالة ، تم إضافة coroutines في C ++ 20 (وظائف يشبه سلوكها المولدات في Python): يمكن تأخير التنفيذ من خلال إرجاع بعض القيمة الحالية مع الحفاظ على الحالة الوسيطة. وبالتالي ، فإننا لا نحقق العمل مع البيانات فقط كما تظهر ، ولكن أيضًا نقوم بتغليف كل المنطق داخل coroutine معين.

ولكن هناك تطاير في المرهم: في الوقت الحالي يتم دعمها جزئيًا فقط من قِبل المترجمين الحاليين ، كما أنها لا يتم تنفيذها بدقة كما نود: على سبيل المثال ، لا ينبغي استخدام الارتباطات والكائنات المؤقتة في coroutines. بالإضافة إلى ذلك ، هناك بعض القيود على ما قد يكون coroutines ، ووظائف constexpr والبناة / المدمرات ، وكذلك الرئيسية ليست مدرجة في هذه القائمة.

وبالتالي ، فإن coroutines حل جزء كبير من المشاكل مع بساطة منطق معالجة البيانات ، ولكن تطبيقاتها الحالية تتطلب صقل.

المواد:


الحيل C ++ من Yandex.Taxi ، أنطون Polukhin


في نشاطه المهني ، يجب عليك في بعض الأحيان تنفيذ أشياء مساعدة بحتة: غلاف بين الواجهة الداخلية وواجهة برمجة التطبيقات لبعض المكتبات ، أو التسجيل أو التحليل. ومع ذلك ، لا توجد عادة حاجة إلى أي تحسين إضافي. ولكن ماذا لو تم استخدام هذه المكونات في بعض الخدمات الأكثر شعبية في Runet؟ في مثل هذه الحالة ، سيكون عليك معالجة تيرابايت في الساعة من السجلات وحدها! ثم كل مللي ثانية مهمة وبالتالي عليك اللجوء إلى الحيل المختلفة - تحدث أنتون Polukhin عنها.

ولعل المثال الأكثر إثارة للاهتمام هو تطبيق نمط المؤشر إلى التنفيذ (pimpl).

#include <third_party/json.hpp> //PROBLEMS! struct Value { Value() = default; Value(Value&& other) = default; Value& operator=(Value&& other) = default; ~Value() = default; std::size_t Size() const { return data_.size(); } private: third_party::Json data_; }; 

في هذا المثال ، أولاً تريد التخلص من ملفات رأس المكتبات الخارجية - سيتم تجميعها بشكل أسرع ، ويمكنك حماية نفسك من تعارضات الأسماء المحتملة وغيرها من الأخطاء المشابهة.

حسنًا ، لقد قمت بنقل #include إلى ملف .cpp: أنت بحاجة إلى الإعلان الأمامي الخاص بـ API الملفوف ، وكذلك std :: unique_ptr. الآن لدينا عمليات تخصيص ديناميكية وأشياء أخرى غير سارة ، مثل البيانات المنتشرة عبر كومة الذاكرة المؤقتة والضمانات المخفضة. مع كل هذا ، يمكن أن تساعد std :: align_storage.

 struct Value { // ... private: using JsonNative = third_party::Json; const JsonNative* Ptr() const noexcept; JsonNative* Ptr() noexcept; constexpr std::size_t kImplSize = 32; constexpr std::size_t kImplAlign = 8; std::aligned_storage_t<kImplSize, kImplAlign> data_; }; 

المشكلة الوحيدة: تحتاج إلى تحديد الحجم والمحاذاة لكل غلاف - سنقوم بإنشاء قالب pimpl الخاص بنا مع المعلمات <T ، و SizeT ، و AlignmentT> ، ونستخدم بعض القيم التعسفية ، ونضيف إلى destructor فحصًا خمنت فيه كل شيء:

 ~FastPimpl() noexcept { validate<sizeof(T), alignof(T)>(); Ptr()->~T(); } template <std::size_t ActualSize, std::size_t ActualAlignment> static void validate() noexcept { static_assert( Size == ActualSize, "Size and sizeof(T) mismatch" ); static_assert( Alignment == ActualAlignment, "Alignment and alignof(T) mismatch" ); } 

نظرًا لأن T قد تم تحديده بالفعل أثناء معالجة المدمر ، سيتم تفكيك هذا الرمز بشكل صحيح وفي مرحلة التجميع في شكل أخطاء ، سيعرض الحجم وقيم المحاذاة الضروريان اللذان يجب إدخالهما. وبالتالي ، على حساب البدء الإضافي للتجميع ، نتخلص من التخصيص الديناميكي للفئات الملفوفة ، ونخفي واجهة برمجة التطبيقات في ملف .cpp مع التنفيذ ، ونحصل أيضًا على تصميم أكثر ملاءمة للتخزين المؤقت بواسطة المعالج.

بدا تسجيل الدخول والتحليل أقل إثارة للإعجاب ، وبالتالي لن يتم ذكره في هذا الاستعراض.

شرائح التقرير متاحة على الرابط: ["C ++ Taxi Tricks"]

التقنيات الحديثة لحفظ رمزك DRY ، Björn Fahller


في هذا الحديث ، يعرض بيورن فهلر عدة طرق مختلفة للتعامل مع العيوب الأسلوبية مثل الفحوصات الشرطية المتكررة:

 assert(a == IDLE || a == CONNECTED || a == DISCONNECTED); 

هل هذا مألوف؟ باستخدام العديد من تقنيات C ++ القوية التي ظهرت في المعايير الحديثة ، يمكنك تنفيذ نفس الوظيفة بأمان دون أدنى خسارة في الأداء. قارن:

 assert(a == any_of(IDLE, CONNECTED, DISCONNECTED)); 

لمعالجة عدد غير محدود من الاختبارات ، تتم مطالبتك على الفور باستخدام قوالب varadic وعبارات fold. افترض أننا نريد التحقق من مساواة العديد من المتغيرات لعنصر التعداد state_type. أول ما يتبادر إلى الذهن هو كتابة وظيفة المساعد is_any_of:

 enum state_type { IDLE, CONNECTED, DISCONNECTED }; template <typename ... Ts> bool is_any_of(state_type s, const Ts& ... ts) { return ((s == ts) || ...); } 

هذه النتيجة الوسيطة مخيبة للآمال. حتى الآن ، أصبح الرمز غير قابل للقراءة:

 assert(is_any_of(state, IDLE, DISCONNECTING, DISCONNECTED)); 

سوف تساعد معلمات القالب غير النوعية على تحسين الموقف قليلاً. بمساعدتهم ، ننقل عناصر التعداد المذكورة إلى قائمة معلمات القالب:

 template <state_type ... states> bool is_any_of(state_type t) { return ((t == states) | ...); } assert(is_any_of<IDLE, DISCONNECTING, DISCONNECTED>(state)); 

باستخدام auto في معلمة قالب غير نموذجية (C ++ 17) ، يتم ببساطة تعميم النهج على المقارنات ، ليس فقط مع عناصر state_type ، ولكن أيضًا مع الأنواع البدائية التي يمكن استخدامها كمعلمات قالب غير الكتابة:

 template <auto ... alternatives, typename T> bool is_any_of(const T& t) { return ((t == alternatives) | ...); } 

من خلال هذه التحسينات الإضافية ، يتم تحقيق بناء الجملة السريع المطلوب للتحقق منه:

 template <class ... Ts> struct any_of : private std::tuple<Ts ...> { //      tuple        using std::tuple<Ts ...>::tuple;        template <typename T>        bool operator ==(const T& t) const {                return std::apply(                        [&t](const auto& ... ts) {                                return ((ts == t) || ...);                        },                        static_cast<const std::tuple<Ts ...>&>(*this));        } }; template <class ... Ts> any_of(Ts ...) -> any_of<Ts ... >; assert(any_of(IDLE, DISCONNECTING, DISCONNECTED) == state); 

في هذا المثال ، يعمل دليل الاستنتاج على توجيه معلمات بنية القالب المرغوب فيها إلى برنامج مترجم يعرف أنواع وسائط المنشئ.

أكثر إثارة للاهتمام. يعلم Bjorn تعميم الكود الناتج لمشغلي المقارنة بالإضافة إلى == ، ثم للعمليات التعسفية. إلى جانب مثال الاستخدام ، يتم شرح ميزات مثل سمة no_unique_address (C ++ 20) ومعلمات القالب في وظائف lambda (C ++ 20). (نعم ، أصبح بناء جملة lambda أسهل في التذكر - فهذه أربعة أزواج متتالية من الأقواس من جميع الأنواع.) إن القرار النهائي الذي يستخدم الوظائف كأجزاء منشئ يسخن روحي حقًا ، ناهيك عن تعبير tuple في أفضل تقاليد حساب التفاضل والتكامل.

في النهاية ، لا تنسى وضع اللمعان:

  • أذكر أن lambdas هي constexpr مجانا ؛
  • أضف توجيهًا مثاليًا وانظر إلى بناءه القبيح كما هو مطبق على حزمة المعلمات في إغلاق lambda ؛
  • دعنا نوفر للمجمع المزيد من الخيارات للتحسينات مع noexcept الشرطية ؛
  • سنهتم بمخرجات الخطأ الأكثر وضوحًا في القوالب نظرًا لقيم الإرجاع الواضحة لل lambdas. سيؤدي ذلك إلى إجبار المترجم على إجراء المزيد من عمليات التحقق قبل استدعاء وظيفة القالب بالفعل - في مرحلة التحقق من النوع.

لمزيد من التفاصيل ، يرجى الرجوع إلى مواد المحاضرة:


انطباعاتنا


تم تذكر مشاركتنا الأولى في C ++ Russia بسبب ثرائها. كان هناك انطباع بأن روسيا C ++ حدث روحي ، حيث الخط الفاصل بين التعلم والتواصل المباشر غير ملحوظ تقريبًا. كل شيء ، من مزاج المتحدثين إلى المسابقات من شركاء الحدث ، يفضي إلى مناقشات ساخنة. يغطي محتوى المؤتمر ، الذي يتكون من تقارير ، مجموعة واسعة إلى حد ما من الموضوعات بما في ذلك ابتكارات C ++ ، أمثلة من ممارسة المشاريع الكبيرة والاعتبارات المعمارية الأيديولوجية. ولكن سيكون من الظلم حرمان انتباه العنصر الاجتماعي للحدث ، مما يساعد على التغلب على الحواجز اللغوية فيما يتعلق ليس فقط بـ C ++.

نشكر منظمي المؤتمر على الفرصة للمشاركة في مثل هذا الحدث!
يمكنك رؤية مشاركة المنظمين حول الماضي والحاضر والمستقبل لـ C ++ Russia على مدونة JUG Ru .

نشكركم على القراءة ، ونأمل أن تكون إعادة سرد الأحداث مفيدة.

Source: https://habr.com/ru/post/ar481358/


All Articles