سؤال

ولقد وجدت هذا في رمز أعمل في هذه اللحظة واعتقد انه كان سبب بعض المشاكل أواجه.

في رأس في مكان ما:

enum SpecificIndexes{
    //snip
    INVALID_INDEX = -1
};

وبعد ذلك في وقت لاحق - التهيئة:

nextIndex = INVALID_INDEX;

وواستخدام

if(nextIndex != INVALID_INDEX)
{
    //do stuff
}

والتصحيح رمز، لم القيم في nextIndex لا تجعل تماما العمالي (أنها كانت كبيرة جدا)، ولقد وجدت أن أعلن ما يلي:

unsigned int nextIndex;

وهكذا، الإعداد الأولي لINVALID_INDEX كان underflowing وغير موقعة كثافة العمليات ووضع لها عدد هائل. توليت هذا ما كان يسبب مشكلة، ولكن يبحث عن كثب، واختبار

if(nextIndex != INVALID_INDEX)

وكان يتصرف بشكل صحيح، أي بمعنى، أن القرار لم ينفذ جسم إذا عندما كان nextIndex على "+ كبيرة [ف قيمة".

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

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

المحلول

ونعم على كل شيء. ورمز صالح، كما أنها تستخدم بشكل شائع في جانب مكتبة C ++ رمز، وأكثر من ذلك في C ++ الحديث (فمن الغريب عندما ترى هذه هي المرة الأولى ولكن في نمط شائع جدا في الواقع).

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

نصائح أخرى

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

والمقارنة المساواة بين أنواع الموقعة وغير الموقعة آمنة وعادة لا ما كان يقصده المؤلف - سيتم تحويل قيمة قعت لغير موقعة أولا، ويتم تعريف نتيجة لفعل ذلك من قبل C ++ القياسية وبديهية (على الأقل، هو بمجرد أن تعرف نوع الوجهة. ربما باستثناء إذا الأعداد الصحيحة ليست متمم ثنائي، لذلك ربما لا أن بديهية، ولكنه لا يسبب عادة مشاكل).

ومقارنة بالدفع من المرجح أن تؤدي إلى أخطاء. على سبيل المثال:

SpecificIndexes value = INVALID_VALUE;
return (value >= 0);

ويعود كاذبة، ولكن:

unsigned int value = INVALID_VALUE;
return (value >= 0);

ويعود صحيحا. في بعض الأحيان فإن المؤلف لا نقدر الفرق، خصوصا إذا كان نوع من "قيمة" ليس تماما ذلك واضحا عند نقطة الاستخدام. المترجم قد حذروا أيضا عن المثال الثاني، وذلك لأن (قيمة> = 0) هو حشوا.

في الواقع، -1 يلقي ضمنيا إلى قيمة equivalente في غير موقعة عندما يتم تعيينه إلى nextValue. وequivalente غير الموقعة هو القيمة مع نفس التمثيل المختصة بالبت (والذي هو 111111111111 ...، وهذا هو، الحد الأقصى للقيمة غير موقعة).

وفي وقت لاحق، في بيان المقارنة، ويلقي ضمني آخر يحدث.

وهكذا يعمل هذا الآن، ولكن قد يسبب مشكلة في المستقبل. انها ليست ابدا فكرة جيدة لخلط القيم الموقعة وغير الموقعة.

نعم، أعتقد أنها وقعت تتضمن التعدادات. تغيير

unsigned int nextIndex;

إلى

int nextIndex;

ويجب أن تعمل البرنامج.

والمعيار C ++ يسمح للتنفيذ لاستخدام نوع وقعت لتتضمن التعدادات ولكن لا تتطلب ذلك. لذلك، لا يمكن بشكل عام نفترض أنه آمن لوضع الأرقام السالبة إلى التعداد.

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