تجنب الأمراض المنقولة جنسيا غير لائق :: تهيئة السلسلة مع null const char * باستخدام g ++

StackOverflow https://stackoverflow.com/questions/2407711

  •  18-09-2019
  •  | 
  •  

سؤال

هناك أي خيارات G ++ التي يمكنها اكتشاف تهيئة غير لائق من STD :: String مع NULL Const Char *؟

كنت في عملية تحويل بعض الحقول الدولية إلى STD :: سلسلة سلسلة، أي:

struct Foo
{
   int id;
   Foo() : id(0) {} 
};

... تحولت إلى:

struct Foo
{
   std::string id;
   Foo() : id(0) {} //oooops!
};

أنا أغفل تماما تهيئة "معرف" مع 0 و G ++ أعطني أي تحذيرات على الإطلاق. تم اكتشاف هذا الخطأ في وقت التشغيل (STD :: سلسلة Brotionor ألقى استثناءا) ولكن أود حقا اكتشاف هذه الأشياء في وقت الترجمة. هل هناك أي طريقة؟

هل كانت مفيدة؟

المحلول

أعتقد أنه في الواقع سلوك غير محدد وليس فحصه من قبل المحول البرمجي. أنت محظوظ أن هذا التنفيذ يلقي استثناء.

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

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};

نصائح أخرى

لا أستطيع التفكير في طريقة للكشف عن هذا في وقت الترجمة، لذلك كتبت وظيفة منشئ سلسلة تتناول بشكل صحيح مع المؤشرات الفارغة:

//  FUNCTION :      safe_string(char const* pszS)
//  PARAMATERS :    pszS        source string to build a string from (may be NULL or 0-length)
//  DESCRIPTION :   Safely builds a string object from a char*, even a NULL pointer
//  RETURNS :       string

template<class C>
inline basic_string<C> safe_string(const C* input)
{
    if( !input )
        return basic_string<C>();
    return basic_string<C>(input);
}

يمكنني استخدام هذا كلما قمت بإنشاء سلسلة وهناك فرصة قد تكون الإدخال فارغة.

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

void foo(const char* cstr) __attribute__((nonnull (1)));

void bar() {
    foo(0);
}

عندما جمعت مع -Wnonnull (وهو أمر ضمني -Wall) ينتج عنه:

warning: null argument where non-null required (argument 1)

لذلك من حيث المبدأ يجب أن تكون قادرا على تعديل رأس النظام ذي الصلة (أو، أفضل لتجربة، تعديل Home $ / Bits / Basic_String.h Company ثم تجاوز النظام -isystem $HOME) بصورة مماثلة:

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
    __attribute__((nonnull (1)));

ومع ذلك، لا يساعد هذا بسبب (على الأقل 4.0.1) -Wnonnull غير مدعوم في C ++ ويتم تجاهل السمة على ما يبدو. ليس من الواضح لماذا هذا كذلك؛ ربما كان هناك شعور بأنه يتفاعل بشدة مع التحميل الزائد أو شيء ما.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top