مكتبة يوم الموت القياسية

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



ما هو ABI؟


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

لا يمكنك استخدام الرمز الذي تم تصديره في الإصدار الجديد من مكتبتك المترجمة إذا قمت بأي مما يلي:

  • تمت إضافة حقل جديد إلى فصل دراسي موجود
  • تم تغيير معلمات القالب للفئة / الوظيفة ، وحولت وظيفة القالب إلى قالب غير القالب ، أو العكس بالعكس ، وأضاف قالب متغير
  • قم بتطبيق المحدد المضمن على شيء ما
  • تمت إضافة المعلمات الافتراضية في إعلان الوظيفة
  • الإعلان عن طريقة افتراضية جديدة

وأكثر من ذلك بكثير ، ولكن الأمثلة المذكورة أعلاه هي الأمثلة الرئيسية التي ذكرتها اللجنة ، والأمثلة نفسها ، والتي بفضلها تم إتلاف معظم المقترحات في المعيار على الفور. لقد حذفت خيارات انتهاك ABI ، والتي يتم خلالها كسر شفرة المصدر للبرنامج (على سبيل المثال ، حذف أو تغيير الوظائف). مع ذلك، هذا ليس دائما صحيحا. على سبيل المثال ، لا يعني حذف دالة دائمًا كسر شفرة المصدر. std::stringيحتوي على عامل تحويل std::string_view، والذي سأكون سعيدًا بالتخلص منه ، وعلى الرغم من أن حذفه سيؤدي إلى كسر ABI ، إلا أنه لن يؤدي إلى مشاكل كبيرة في شفرة المصدر.

لماذا يجب علينا كسر ABI


بادئ ذي بدء ، هناك العديد من التغييرات المفيدة في تنفيذ المكتبة القياسية التي يمكنك تنفيذها إذا كسرت ABI الحالي:

  • جعل الحاويات النقابية (بكثير) أسرع
  • قم بتسريع عملك std::regex(في الوقت الحالي ، من الأسرع تشغيل PHP والبحث عنه بتعبير عادي من استخدام التعبير القياسي std::regex)
  • بعض التغييرات في std::string، std::vectorوكذلك في تخطيط الحاويات الأخرى
  • وحدة الواجهة الصفية: في الوقت الحالي ، لا تتوافق بعض عمليات التنفيذ عن عمد مع واجهة واحدة من أجل استقرار ABI

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

  • std::scoped_lock تمت إضافته حتى لا يكسر تغيير أبي lock_guard
  • int128_t , intmax_t. , , , intmax_t deprecated
  • std::unique_ptr , zero-overhead
  • error_code - , ABI
  • status_code ABI
  • recursive_directory_iterator , ABI
  • <cstring> constexpr ( strlen) , ABI
  • UTF-8 std::regex — ABI
  • إضافة دعم إلى reallocحجم الذاكرة المخصصة وإعادتها هو تقسيم ABI لمخصصات متعددة الأشكال
  • إنشاء مدمرات افتراضية ضمنية لأنواع متعددة الأشكال
  • push_backيمكن تغيير نوع الإرجاع y إذا تم كسر ABI الحالي
  • بشكل عام ، هل نحن حقا بحاجة و push_back، و emplace_back؟
  • std::shared_ptr كما يتسبب في انهيار ABI
  • [[no_unique_address]] يمكن أن يخرج من قبل المترجم إذا لم نكن نهتم بحفظ ABI الحالي

والقائمة لا تنتهي عند هذا الحد. أعتقد أن WG21 يجب أن تحاول تحديث قائمة هذه الأشياء. لكني سأحيط علما بكل من يقول "سوف يكسر ABI" ، كونه معي في نفس الغرفة.

ما الذي نريد تغييره أيضًا؟


لا أدري، لا أعرف. ولا أعرف ما لا أعرفه. ولكن إذا طُلب مني أن أخمن ، سأقول ما يلي:

  • C++23 ABI, - , ABI.
  • , , , , ABI
  • ABI,
  • , ABI
  • Tombstone ABI

ABI


خلال مناقشة ABI الأخيرة ، تم إجراء عدد من الاستطلاعات في براغ ، ومع ذلك ، لا تخبرنا بأي شيء. اعتمادًا على ما إذا كنت متشائمًا أو متفائلًا ، يمكن تفسير النتائج الحالية بشكل مختلف.

مفتاح الحقائق:

  • WG21 لا تريد كسر ABI في 23
  • تعتبر WG21 أنه من الضروري كسر ABI في الإصدارات المستقبلية من C ++ (C ++ 26 أو أحدث)
  • سوف يستغرق WG21 وقتًا للنظر في المقترحات التي تنتهك ABI
  • WG21 لا تعد بالاستقرار الأبدي
  • تعتبر WG21 أنه من المهم الحفاظ على الأولوية في الأداء ، حتى على حساب استقرار اللغة

تحتوي هذه البيانات على العديد من النقاط المهمة ، ولكن لا يوجد توافق في الآراء. اللجنة ، من الغريب ، انقسمت إلى النصف.

الكهانة


في أي إصدار من C ++ لانتظار التغييرات


العيب الواضح لجميع هذه الاستطلاعات هو أننا لم نقرر متى نريد بالضبط كسر ABI.

في ج + + 23؟ لا ، بالتأكيد ليس بالفعل.

في C ++ 26؟ ينوي بعض الأشخاص التصويت لصالحه ، ولكن من المرجح أن يصوت جزء آخر لـ C ++ 41 أو في الوقت الذي يتقاعدون فيه وليس عليهم دعم مشروعهم الحالي. أحد الأسئلة التي ذكرت للتو C ++ - بعضها ؛ مريح للغاية!

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

لا أعتقد أن شيئًا ما سيتغير في المسح الذي أجري خلال ثلاث سنوات. إنه مثل الاحتباس الحراري: يتفق الجميع على أننا نحتاج يومًا ما إلى معالجة هذه المشكلة. ثم لنحظر الديزل عام 2070؟

من غير المحتمل أن يحدث كل شيء من غير المقرر القيام به في السنوات الخمس المقبلة.

حول العروض التي تنتهك ABI


صوتت WG21 لتخصيص مزيد من الوقت للمقترحات التي تنتهك ABI الحالي. هذا يعني بعض الأشياء:

  • سنضيع المزيد من الوقت في واحدة من أكثر غرف اللجنة ضجيجًا لمناقشة هذه المسألة ونترك القليل لتلك الاقتراحات التي لديها فرص أكثر للاعتماد ، وفي النهاية سنرفضها جميعًا بنفس الطريقة
  • سنبحث عن بدائل لا تكسر ABI (سيتم مناقشة هذا أدناه)
  • قد يتم إدخال تغييرات جزئية في ABI (انظر أيضًا أدناه)

الأداء أكثر أهمية من استقرار ABI


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

يبدو لي أن اللجنة تريد في الوقت نفسه الجلوس على كرسيين في وقت واحد. وهذا مستحيل:
برايس Adelstein Lelbach blebach
- الأداء
- الاستقرار ABI
- القدرة على تغيير شيء

اختر خيارين من تلك المقترحة.

بالطبع ، يصطدم استقرار اللغة و ABI مع بعضها البعض ، مما يجبرنا على طرح مثل هذا السؤال الأساسي - ما هو C ++ وما هي مكتبته القياسية؟

عادة في هذه الحالة ، يتم تذكر مصطلحات "الأداء" و " التجريد بدون تكلفة " و " لا تدفع مقابل ما لا تستخدمه ". واستقرار ABI يقف في كل هذا.

عواقب بعيدة المدى


صورة

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

كابوس التعلم


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

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

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

رفضًا لانتهاك ABI ، صرحت اللجنة علناً أنها ستدعم البرامج المكتوبة بشكل سيئ طوال فترة وجودها. حتى إذا لم تقم بالارتباط بالمكتبات التي تم الحصول عليها من خلال apt-install (والتي هي في الواقع مخصصة للنظام) ، فسيكون هناك أشخاص آخرون ، لأن اللجنة أعطتهم البركة.

هذه خطوة كبيرة إلى الوراء. كيف يمكننا تعليم الآخرين ممارسات لغوية جيدة إذا لم يكن لدينا حافز للقيام بذلك؟

فقدان الاهتمام بالمكتبة القياسية


تُقدَّر الخسائر المقدرة في أداء المكتبة بسبب عدم استعدادنا لانتهاك ABI بنسبة 5-10٪. سوف ينمو هذا الرقم فقط مع مرور الوقت. دعونا نلقي نظرة على الأمثلة:

  • إذا كنت شركة كبيرة ، يمكنك شراء مركز بيانات جديد لنفسك أو الدفع لفريق من المبرمجين الذين يدعمون مكتبتهم الخاصة
  • , 5% ,
  • , 5-10% , VR-
  • , —

أعتقد ، هنا ، ويلي-نيلي ، أن السؤال الذي يطرح نفسه هو: "بالتأكيد يجب علي استخدام C ++ ومكتبتها القياسية!" و "ربما لا ينبغي لي استخدام المكتبة القياسية؟ أو ربما لا ينبغي لي استخدام C ++ من حيث المبدأ؟ ربما يكون .NET أو julia أو Rust هو الحل الأفضل؟ " بالطبع ، هناك العديد من العوامل التي تؤثر على الإجابة ، لكننا نرى ما يحدث مؤخرًا.

يشكك العديد من مطوري الألعاب في المكتبة القياسية. إنهم يفضلون تطوير بديلهم الخاص ، مثل EASTL ، بدلاً من الاستفادة من STL. الفيسبوك لديه حماقة ، وجوجل لديها abseil وهلم جرا.

إنها مثل كرة الثلج. إذا لم يستخدم الأشخاص المكتبة القياسية ، فلن يكون لديهم مصلحة في تحسينها. الأداء هو العامل الرئيسي الذي يحافظ على المكتبة طافية. بدون ضمان الأداء ، سيتم بذل جهد أقل في تطويره.
>> Jonathan Müllerfoonathan
ما الفائدة من استخدام الحاويات من المكتبة القياسية إذا لم تقدم أداءً أفضل؟

Titus WintersTitusWinters
ربما لأنها شائعة ويمكن الوصول إليها بسهولة؟ (هاتان الحقائقان لا تعنيان نفس الشيء).
التصويت للحفاظ على ABI هو مثل القول بأن المكتبة القياسية يجب أن تسعى إلى أن تكون ماكدونالدز - فهو أيضًا في كل مكان ، وهو مستقر ويحل المهام تقنيًا.

كيف يمكن للجنة النظر في مقترحات كسر ABI؟


يتم تقديم العديد من الخيارات لتخفيف الألم الناجم عن عدم القدرة على قبول العروض إذا انتهكت ABI:

إضافة أسماء جديدة


صورة

هذا هو الحل الأول والواضح. إذا لم نتمكن من التغيير std::unordered_map، فهل يمكننا فقط الإضافة std::fast_map؟ هناك عدة أسباب تجعل هذا سيئًا. إن إضافة أنواع إلى المكتبة القياسية أمر مكلف ، سواء من حيث تكاليف الدعم أو من حيث التعليم. بعد تقديم الفصل الجديد ، ستظهر آلاف المقالات حتمًا ، لتوضيح الحاوية التي يجب استخدامها. على سبيل المثال ، هل يجب علي استخدام std::scoped_lockأو std::lock_guard؟ ليس لدي أي فكرة! أحتاج إلى google في كل مرة. هناك أيضًا مشكلة أن تنتهي الأسماء الجيدة عاجلاً أم آجلاً. نحصل أيضًا على بعض النفقات العامة أثناء تنفيذ البرنامج ، نظرًا لأنه يجب تحويل جميع الحاويات باستمرار إلى بعضها البعض ، يصبح من الصعب التحكم في عدد كبير من حمولات التحويل الزائدة في الفصل ، إلخ.

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

ولكن يمكننا قبول هذا العرض كمعيار!


يدعي بعض مطوري المكتبات أن عروضهم تم رفضها بسبب انتهاك ABI ، على الرغم من أنهم لم ينتهكوا أي شيء في الواقع ، أو يمكن تغييرهم للتحايل على فشل ABI.

كشخص ساخر ، من الصعب بالنسبة لي أن أصدق. والحقيقة هي أنه قبل عدم وجود مثل هذه الاقتراحات ، والسيناريوهات التي يمكن تطبيقها فيها محدودة للغاية. يمكن أن تساعد ABI Review Group (ARG) في هذه المسألة ، ولكن من المحتمل أن يوصوا مرة أخرى باسم آخر للفئة / الوظيفة.

انتهاك أبي الجزئي


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

مستوى آخر من الفهرسة


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

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

ونتيجة لذلك ، سيكون سعر هذا النهج باهظًا.

كحل لهذه المشكلة ، هناك بالفعل العديد من المقترحات في المعيار. يريد البعض منهم جعل PIMPL أحد ميزات اللغة ، بحيث يمكنك الاختيار بين استقرار ABI والأداء العالي.

ومع ذلك ، من المفارقات ، ولكن من أجل تحويل أنواع المكتبة إلى أنواع PIPML ، نحتاج إلى ... كسر ABI.

أعد تجميع كافة التعليمات البرمجية كل ثلاث سنوات


فقط أفكاري بصوت عال.

يجب تدمير جميع العروض الحالية في المعيار


من المفارقات أن C ++ لم تكن أبدًا حية كما هي الآن. في براغ ، عمل 250 شخصًا على العديد من الأشياء له ، بما في ذلك:

  • الأعداد
  • الجبر الخطي
  • صوت
  • يونيكود
  • I / O غير متزامن
  • رسومات ثنائية الأبعاد وثلاثية الأبعاد
  • العديد من الميزات الأخرى

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

وبعد ذلك ، تلوح في الأفق رعب مثل الشبكات . من غير المسؤول للغاية محاولة توحيد أي شيء قد يؤدي إلى مشاكل أمنية ، وفي نفس الوقت لن يكون قادرًا على تغييره لاحقًا (تذكر ABI).

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

لكنهم ما زالوا لن يفعلوا ذلك.

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

لكن بالطبع ، سنرتكب الكثير والكثير من الأخطاء.

>> Ólafur Waage @olafurw
( , )

, !

. , ( : , , )?

Hyrum Wright @hyrumwright
, , . — , .

يتم ارتكاب بعض الأخطاء عن قصد ، لأنها مقايضات ، بينما لا يلاحظ البعض الآخر لسنوات عديدة.

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

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

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

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

عرضك بالمعيار ، وسيتم تدمير عرضي بنفس الطريقة.

هل يمكن للجنة من حيث المبدأ كسر ABI؟


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

لكن الحقيقة هي أن مطوري أي منتج لديهم مستخدمين خاصين بهم. المستخدمون هم أولئك الذين يحتاجون أولاً إلى فهم مفاضلاتهم المفروضة عليهم.

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

All Articles