التهيئة بين الأنواع "const int ** const" و "int **" غير مسموح بها، لماذا؟

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

سؤال

باستخدام مترجم V1.8 Z / OS XL C مترجم، مع تحذيرات Jacked-Up باستخدام معلومات (ALL)، أحصل على التحذير التالي على السطر 4 من التعليمات البرمجية أدناه:

WARNING CCN3196 Initialization between types "const int** const" and "int**" 
                is not allowed.


1  int foo = 0;
2  int *ptr = &foo;

3  const int * const fixed_readonly_ptr = ptr;

4  const int ** const fixed_ptr_to_readonly_ptr = &ptr;

لا أستطيع التفاف رأسي حول سبب تلقي هذا التحذير. إذا استطعت تعيين مؤشر INT إلى مؤشر CONST إلى CONST INT INT (السطر 3)، فلماذا لا يمكنني تعيين عنوان مؤشر INT إلى مؤشر CONST إلى المؤشر إلى المؤشر إلى Const Int؟ ماذا ينقصني؟

ملاحظة التعليمات البرمجية أعلاه هي مثال لأسفل منخفضا فقط إظهار المشكلة التي صرفها في كمية صغيرة من التعليمات البرمجية. السياق الحقيقي هو أن لدي مؤشر CONST إلى المؤشر إلى الهيكل (بنية S ** CONST) وأمره كحجة لموظيفة المعلمة التي يتم تعريفها على أنها مؤشر CONST إلى المؤشر إلى Const Form S ** مقدار ثابت). وذلك لأن الوظيفة لن تقوم بتعديل البيانات الموجودة في الهيكل (وبالتالي أول const) ولا تعدل معلمة المؤشر التي تحمل العنوان الذي تم تمريره دائما (وبالتالي الثانية الثانية). قد يتم تغيير قيمة المؤشر المشار إليها بالمناسبة (وهذا هو السبب في عدم وجود ثالث ثابت بين **).

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

المحلول

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

الأساس المنطقي لهذه القاعدة هو أنه إذا تم السماح الثاني من هذين السطرين:

int *ptr;

const int ** const fixed_ptr_to_readonly_ptr = &ptr;

ثم يمكن استخدام هذا لكسر السلامة من النوع دون إيصال.

const int i = 4;

// OK, both sides have type const int *
*fixed_ptr_to_readonly_ptr = &i;

// the value of fixed_ptr_to_readonly_ptr is still &ptr
// the value of ptr is now &i;

*ptr = 5;

// oops, attempt to change the value of i which is const

نصائح أخرى

إنه انتهاك سلامة النوع. النظر في هذا الرمز (أنا خلط const حول بعض الشيء لتتحسين ما إذا كان ينطبق على المؤشر أو المدبب، ولكنه يعني ذلك بشكل صحيح نفس الشيء):

int* p = 0;
int const** pp = &p; // presumably ok

int const c = 123;
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue

*p = 666; // okay, *p is int lvalue

// wait, so we just changed the value of (const) c above, with no const_cast!

هذا هو انتهاك سلامة النوع. ربما تريد استخدام const int * const * بدلا من ذلك. يرى http://www.parashift.com/c+--faq-lite/const-ctrectness.html#faq-18.17.

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