سؤال

لقد رأيت وظيفة الذي النموذج هو:

int myfunc(void** ppt)

يتم استدعاء هذه الدالة في ملف C a = myfunc(mystruct **var1);

حيث mystruct هو typedef واحد من هيكل لدينا.

هذا يعمل من دون أي أخطاء التحويل البرمجي في MSVC6.0 ، ولكن عندما تجمع مع بعض ج مترجم ، فإنه يعطي خطأ في المكان حيث يتم استدعاء هذه الدالة مع رسالة الخطأ:

حجة من نوع mystruct ** غير متوافق مع معلمة من نوع void **

حجة myfunc() يتم الاحتفاظ بها باطل** لأنه يبدو أن عام malloc نوع من وظيفة تسمى مع مختلف هيكل متغير أنواع تخصيص الذاكرة

  1. هل هناك أي نوع مثل الفراغ ** يسمح في C القياسية/أي ج compilers ؟
  2. كيف يمكنني إصلاح هذا ؟ [حاولت صب استدعاء دالة حجة mystruct**, لكنه لم ينجح]

-AD

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

المحلول

void** هو صالحة ولكن استنادا إلى رسالة الخطأ الخاصة بك, ربما لديك صراحة يلقي الحجة على النحو التالي:

mystruct **var1;
x = myfunc ((void**) var1);

ذلك لأن myfunc وظيفة يتوقع void** نوع.في حين void* يمكن أن يكون ضمنيا يلقي أي مؤشر, لا عن ضعف مؤشر تحتاج إلى صراحة يلقي ذلك.

نصائح أخرى

على comp.لانغ.ج التعليمات تتناول هذه المسألة بالتفصيل في السؤال 4.9.باختصار يقولون ليس بدقة المحمولة أن يلقي التعسفي المؤشر إلى مؤشر إلى void **;يذهبون إلى شرح أن "التعليمات البرمجية مثل هذا قد تعمل في بعض الأحيان ، ولكن ذلك يعتمد على كل مؤشر الأنواع لها نفس التمثيل الداخلي (وهو أمر شائع ولكن ليس عالمي)." يذهبون إلى شرح أن "أي void ** قيمة كنت العب مع يجب أن يكون العنوان الفعلي void * القيمة في مكان ما ؛ يلقي مثل (void **)&dp, ، على الرغم من أنها قد تغلق مترجم ، nonportable (و قد لا تفعل ما تريد)."

بحيث يمكنك بأمان/portably تحقيق السلوك المطلوب مع رمز مثل:

some_type *var1 = foo();
void *tmp_void_ptr = (void *)var1;
myfunc(&tmp_void_ptr);

هناك سبب المترجم لا يمكن تلقائيا المدلى بها من mystruct** إلى void**.

النظر في التعليمات البرمجية التالية:

void stupid(struct mystruct **a, struct myotherstruct **b)
{
    void **x = (void **)a;
    *x = *b;
}

المترجم لا يشكو ضمني من الزهر myotherstruct* إلى void* في *x = *b خط, على الرغم من أن خط تحاول وضع مؤشر إلى myotherstruct في مكان حيث لا يوجد سوى مؤشرات mystruct ينبغي أن توضع.

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

هذا السؤال قليلا مربكة.ولكن نعم ، void ** هو بالتأكيد القانونية سارية المفعول ج ، يعني "مؤشر إلى مؤشر void"كما هو متوقع.

أنا لست متأكدة من مكالمة الحجج ("mystruct **var1") لا معنى له.إذا var1 هو من نوع mystruct **, الدعوة ينبغي أن مجرد قراءة a = func(var1);, هذا قد يكون خطأ مطبعي.

الصب يجب أن تعمل ، ولكن عليك أن يلقي void **, لأن هذا هو ما تتوقع وظيفة.

كما القذرة أنها قد تبدو وكأنها:في بعض الأحيان كنت لا يمكن حل المشكلة دون استخدام الفراغ **.

نعم ، void ** هو مقبول تماما و مفيدة جدا في ظروف معينة.أيضا ضع في الاعتبار أن ضوء إعلان void **foo و void *bar, المحول البرمجي سوف تعرف حجم الكائن أشار إليه فو (من نقطة إلى المؤشر ، وكل المؤشرات هي نفس الحجم إلا على عدد قليل القديمة منصات كنت لا داعي للقلق حول) ، لكنها لن تعرف حجم الكائن المشار إليه بواسطة شريط (يمكن أن نشير إلى كائن من أي حجم).ولذلك يمكنك بأمان أداء المؤشر على الحساب void ** ولكن المؤشرات لا على void * المؤشرات.يجب أن يلقي بها إلى شيء آخر أولا ، مثل char *.دول مجلس التعاون الخليجي سوف تسمح لك أن تدعي أن void * و char * تعادل كل لافتا إلى كائن واحد بايت في الحجم ، ولكن هذا غير قياسي و nonportable.

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