هل استخدام const_cast للوصول إلى القراءة فقط إلى كائن const مسموح به؟

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

سؤال

في C ++ ، لدي وظيفة لا تتطلب سوى الوصول للقراءة فقط إلى صفيف ولكن يتم إعلانها عن طريق الخطأ على أنها تلقي مؤشر غير مؤشر:

size_t countZeroes( int* array, size_t count )
{
    size_t result = 0;        
    for( size_t i = 0; i < count; i++ ) {
       if( array[i] == 0 ) {
           ++result;
       }
    }
    return result;
}

وأحتاج إلى تسميتها لمجموعة كونستور:

static const int Array[] = { 10, 20, 0, 2};

countZeroes( const_cast<int*>( Array ), sizeof( Array ) / sizeof( Array[0] ) );

هل سيكون هذا سلوكًا غير محدد؟ إذا كان الأمر كذلك - متى سيواجه البرنامج UB - عند القيام بـ const_cast والاتصال بـ functon أو عند الوصول إلى الصفيف؟

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

المحلول

نعم ، يُسمح بذلك (إذا كان خطيرًا!). إنها الكتابة الفعلية إلى const الكائن الذي يتحمل السلوك غير المحدد ، وليس يلقي نفسه (7.1.5.1/4 [dcl.type.cv]).

كما الملاحظات القياسية في 5.2.11/7 [expr.const.cast] ، اعتمادا على نوع الكائن محاولة الكتابة من خلال مؤشر هو نتيجة الابتعاد const قد تنتج سلوك غير محدد.

نصائح أخرى

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

نعم يمكنك ان تفعل. لا ، إنه ليس سلوكًا غير محدد طالما أن الوظيفة حقًا لا تحاول الكتابة إلى الصفيف.

مشكلة const_cast هو نفسه دائمًا - يتيح لك "كسر القواعد" ، تمامًا مثل الصب من وإلى void* - بالتأكيد يمكنك القيام بذلك ، ولكن السؤال هو لماذا يجب عليك؟

في هذه الحالة ، لا بأس بالطبع ، لكن يجب أن تسأل نفسك لماذا لم تعلن size_t countZeroes( const int* array, size_t count ) في المقام الأول؟

وكقاعدة عامة حول const_cast:

  1. قد ينتج جاهدة للعثور على الأخطاء
  2. أنت ترفع الوفرة مع المترجم
  3. في الأساس ، تقوم بتحويل اللغة إلى مستوى أقل.

استخدام const_cast على كائن يتم تعريفه في البداية على أنه const هو UB ، وبالتالي فإن السلوك غير المحدد يأتي مباشرة عند النقطة التي تتصل بها const_cast.

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