هل يُظهر تعبير تسلسل السلسلة في كود Bjarne Stroustrup سلوكًا غير محدد؟
في الإصدار الرابع من "لغة البرمجة C" لـ Bjarne Stroustrup ، مقتطف التعليمات البرمجية يجسد التسلسل باستخدام طريقة استبدال std::string:
void f2() {
std::string s = "but I have heard it works even if you don't believe in it";
s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");
assert(s == "I have heard it works only if you believe in it");
}
ومع ذلك، يعرض هذا الرمز سلوكًا غير محدد بدلاً من استدعاء سلوك غير محدد.
يكمن سبب هذا السلوك غير المحدد في ترتيب التقييم، وهو غير محدد لـ التعبيرات الفرعية لاستدعاءات الوظائف المتسلسلة. في هذه الحالة، يتم تقييم استدعاءات الدالة s.find إما قبل أو بعد استدعاء s.replace الأول، مما يؤدي إلى تغيير طول السلسلة الناتجة والتأثير على نتيجة استدعاء البحث التالي.
يوضح المثال في السؤال ما يلي: عندما يتم تقييمها من قبل مترجمين مختلفين (clang، gcc)، يتم الحصول على نتائج مختلفة بسبب اختلاف أوامر التقييم.
التفاصيل
تحتوي وسيطات الدالة على ترتيب تقييم غير محدد، بينما يقدم تسلسل استدعاءات الدوال ترتيب تقييم من اليسار إلى اليمين لكل استدعاء دالة، ويتم تسلسل وسيطات كل استدعاء قبل فقط فيما يتعلق بـ استدعاء دالة معينة.
في المثال، ينشأ عدم التحديد هذا في تقييم s.find("even") وs.find("dot") فيما يتعلق بـ s.replace(0, 4, "").
تجاهل المزيد من العناصر الفرعية - يمكن وصف تفاصيل التعبير وتسلسل خطوات التقييم وترابطها على النحو التالي:
Step 1: s.replace(0, 4, "") // A Step 2: s.find("even") // B Step 3: s.replace(B, 4, "only") // C Step 4: s.find("don't") // D Step 5: s.replace(D, 6, "") // E
بينما يتم تسلسل A قبل B، والذي يتم تسلسله بدوره قبل C، لا توجد علاقة تسلسل بين B وD فيما يتعلق بـ A. ونتيجة لذلك، يمكن تقييم D إما قبل A أو بعده، مما يؤدي إلى نتائج مختلفة بناءً على التسلسل المختار.
C 17 التغييرات
يعزز معيار C 17 ترتيب قواعد التقييم للتعبيرات اللاحقة وقائمة التعبيرات الخاصة بها، مما يمنح الكود المعني سلوكًا محددًا جيدًا. التسلسل هو كما يلي:
وبالتالي، في C 17 والإصدارات الأحدث، سيتم تقييم هذا الرمز دائمًا بشكل صحيح.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3