سؤال

لا يعطي الكود التالي تحذيرا مع G ++ 4.1.1 و -Wall.

int octalStrToInt(const std::string& s)
{    
    return strtol(s.c_str(), 0, 8);
}

كنت أتوقع تحذيرا لأن Strtol يعيد long int لكن وظيفتي تعود سوى عادي int. وبعد قد ترجمات محكمات أخرى تنبعث منها تحذير هنا؟ يجب أن ألقي قيمة العودة إلى int في هذه الحالة كممارسة جيدة؟

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

المحلول

قد تحتاج إلى علامة -wconversion لتحويل هذه التحذيرات. ومع ذلك، لن يحذر طويل -> إتجاه, ، نظرا لأنها نفس الحجم مع دول مجلس التعاون الخليجي (لن تتغير القيمة بسبب التحويل). لكنه سوف تفعل ذلك على سبيل المثال طويل -> قصيرة

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

نصائح أخرى

أفضل نهج هو:

long x = strtol(...); assert(x <= INT_MAX); return (int)x;

انت تحتاج limits.h و assert.h

إذا لم يكن لديك الوصول إلى boost::numeric_cast, ، يمكنك كتابة تقليد بسيط:

template <typename T, typename S>
T range_check(const S &s) {
    assert(s <= std::numeric_limits<T>::max());
    assert(s >= std::numeric_limits<T>::min());
    return static_cast<T>(s); // explicit conversion, no warnings.
}

return range_check<int>(strtol(some_value,0,8));

في الواقع هذا قليلا من الغش، لأنه لا يعمل لأنواع الوجهة العائمة. min() ليست هي نفسها مرتبطة بها لأنها هي لأنواع عدد صحيح، تحتاج إلى التحقق من +/- max(). وبعد ممارسة للقارئ.

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

هناك ايضا boost::lexical_cast (خارج اليد أنا لا أعرف كيفية جعل ذلك قراءة ثمكتال) و stringstream. اقرأ النوع الذي تريده، وليس النوع الذي يحدث له وظيفة مكتبة C لذلك.

لا ترى أي تحذير هنا، لأن البيانات الخاصة ب "Int" و "Long Int" على منصاتك لها نفس الحجم والمدى. اعتمادا على الهندسة المعمارية، يمكن أن تصبح مختلفة.

لحماية نفسك من الأخطاء الغريبة، واستخدام فحص النطاق. أقترح عليك استخدام STD :: Numeric_limits :: Min / Max (انظر).

بعد Range التحقق، يمكنك استخدام المصبوب STATIC_CLAST أو C STOME.

من ناحية أخرى، يمكنك الاعتماد على نفس الوظيفة المنفذة في STD :: StringStream Class. سيكون التحويل باستخدام STD :: Stringstream آمنة من النظام الأساسي والنوع آمنا افتراضيا.

ستحذر معظم المجمعين الحديسين من التحويل والاقتراضات المحتملة حسب مستوى التحذير الذي قمت بتكوينه. على MSVC التي تحذر المستوى 4.

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

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