برينتف:%p بمؤشر NULL
سؤال
بينما كنت أكتب اختبار الوحدة، عثرت على بعض السلوكيات الغريبة من glibc
, ، متعلق "%p"
و ال NULL
المؤشر.
إذا كان لدي خط مثل printf("NULL pointer is %p\n", NULL);
, ، ثم أرى NULL pointer is (nil)
المطبوعة على الشاشة، كما كنت أتوقع.
إذا استخدمت بدلاً من ذلك الإصدار واسع الأحرف: wprintf(L"NULL pointer is %p\n", NULL);
, ، ثم تتم طباعته NULL pointer is (
, ، ويتوقف عند قوس الافتتاح.إذا قمت بطباعة غيرNULL
المؤشر، فإنه يطبع هذا المؤشر، سواء الإصدارات العادية أو ذات الأحرف العريضة.هل هذا خطأ معروف في glibc
, ، أم أنني أفتقد شيئًا ما؟
ملحوظة:أدرك أن معيار C يقول أن المؤشرات مع %p
يتم تحويلها بطريقة محددة التنفيذ؛يبدو من غير المعتاد الطباعة فقط (
ل NULL
المؤشر.
المحلول
هذا هو بالتأكيد خلل: https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=stdio-common/vfprintf.c;hb=c15cf13a8a672bd27bf3d94b995c52872eed537d#l932
934 /* Write "(nil)" for a nil pointer. */ \
935 string = (CHAR_T *) L_("(nil)"); \
936 /* Make sure the full string "(nil)" is printed. */ \
937 if (prec < 5) \
938 prec = 5; \
939 is_long = 0; /* This is no wide-char string. */ \
940 goto LABEL (print_string); \
ال L_("(nil)")
يتسع ل L"(nil)"
لwprintf، ولكن بضعة أسطر في وقت لاحق is_long
تم ضبطه على 0
(أي.خطأ شنيع).نتيجة ل string
يتم تفسيرها على أنها سلسلة ذات أحرف ضيقة، لذا فإن طباعتها ستتوقف عند أول بايت صفري، أي.بعد (
.
رابط الخطأ الذي تم الإبلاغ عنه: https://sourceware.org/bugzilla/show_bug.cgi?id=16890 - تم إصلاح هذا في الإصدار 2.20 من glibc.
ومن المثير للاهتمام أن هذا الخطأ يبدو أنه كان موجودًا منذ ما يقرب من 15 عامًا قبل العثور عليه وإصلاحه - في غضون يومين من الإبلاغ عنه!
نصائح أخرى
تم التأكيد على Ubuntu 14.04 LTS؛مكتبة جنو سي (Ubuntu EGLIBC 2.19-0ubuntu6).
يبدو أن أ تم الإبلاغ عن خطأ على الأقل في دبيان glibc؛الحشرة تم إصلاح في 1 مايو 2014، ويجب أن يكون متاحًا في Glibc 2.20.فقط انتظر التحديثات الأولية.