دالة strtod في لغة C تُبلّغ عن الخطأ بطريقتين مختلفتين بين glibc وmusl
المغزى: هذا النوع من الفروق لا يُسقط البناء ولا يرمي خطأ، بل يعطي قيمة صامتة مختلفة، فالكود الذي اختُبر على جهاز المطوّر قد يسلك سلوكًا آخر داخل حاوية Alpine.
نُشرت في 9 أكتوبر 2026 مقالة تختبر سلوك الدالة strtod في لغة C، وهي الدالة التي تحوّل نصًا إلى عدد عشري. وتمرّر المقالة للدالة نصًا لا يصلح أصلًا، هو الحرف x وحده، ثم تقارن ما تفعله مكتبتان شائعتان من مكتبات C على Linux.
والنتيجة أن مكتبة glibc تترك قيمة errno، وهي المتغير الذي تُبلّغ به الدوال عن الخطأ، على صفر. أما مكتبة musl فتضعها على EINVAL، أي القيمة 22. ويقول الكاتب إن هذا السلوك غير موثّق إطلاقًا في صفحة الـ man على Linux.
وأصل الخلاف في المعايير نفسها. فمعيار C يربط الإبلاغ عن الخطأ بقيمة math_errhandling، ويترك للتطبيق أن يقرر هل تأخذ errno القيمة ERANGE في حالة underflow، أي حين يكون العدد أصغر من أن يُمثَّل. أما معيار POSIX فيقول إن errno تُضبط على ERANGE في هذه الحالة. وفي حالة الإدخال غير الصالح، يقول POSIX إن errno يجوز أن تُضبط على EINVAL، دون أن يُلزم بذلك. فكل مكتبة تتبع قراءة مختلفة، وكلتاهما تستطيع أن تقول إنها ملتزمة.
وتوصية الكاتب ألّا يُعتمد على errno هنا، وأن يُفحص المؤشر endptr: فإن ساوى بداية النص، فالتحويل لم يحدث. ويرى أن المعيار يحتاج إلى صياغة أوضح.
ولا يقتصر الأثر على من يكتب C مباشرة. فصور Alpine، الشائعة في بناء الحاويات لصغر حجمها، تعمل بمكتبة musl، بينما تعمل أغلب توزيعات Linux على أجهزة المطورين بمكتبة glibc. ولذلك قد يسلك الكود نفسه، أو مكتبة مكتوبة بـ C يعتمد عليها، سلوكًا مختلفًا داخل الحاوية عمّا كان عليه أثناء الاختبار، دون أي رسالة خطأ تنبّه إلى ذلك.