سؤال

وأنا أحاول لبناء cairomm لgtkmm على النوافذ باستخدام مينغو. فواصل تجميع في استدعاء دالة الذي يحتوي على معلمة التي يقوم reinterpret_cast من منطقي إلى الفراغ *.

cairo_font_face_set_user_data(cobj(), &USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS, reinterpret_cast<void*>(true), NULL);

وهذا هو المكان الذي فواصل الرمز، والسبب هو "reinterpret_cast صالح من منطقي بها باطل *". لماذا يحدث هذا، وكيف يمكنني تعديل هذا الخط للحصول عليه لتجميع؟ بحاجة الى مساعدة

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

المحلول

وأرى أن هذا هو بيانات المستخدم ولديك السيطرة على ما يحدث مع القيمة، ويلقي منطقي إلى int أولا: reinterpret_cast<void *> (static_cast<int> (true)). تفعل هذا الأمر يبدو معقولا تماما في هذا الفراغ * المعلمة يأخذ مكان ظائف القالب في هذه المكتبة ANSI-C. كل ما تحتاجه هو صواب / قيمة زائفة. لذا، ينبغي أن يكون هناك أي خطر في ترميز مؤقتا هذا كمؤشر طالما تم توثيقه جيدا على هذا النحو. حقا، هل ستكون أفضل حالا مع هذا: reinterpret_cast<void *> (1) أو reinterpret_cast<void *> (+true)

نصائح أخرى

ويبدو أنه يجب أن تعمل وفقا لهذا المعيار. يقول القسم 3.9.1-7 منطقي هو نوع لا يتجزأ، و5.2.10-5 يقول قيمة من نوع لا يتجزأ يمكن تحويلها صراحة إلى مؤشر استخدام reinterpret_cast. ويبدو أن المترجم الخاص بك غير القياسية تماما.

هل يمكن أن تفلت من تغيير "حقيقي" ل1؟ تحويل بين الأعداد الصحيحة وأنواع المؤشر هو تقليد قديم وغير نزيه فى C وبالتالي C ++، وسيكون من المستغرب أن نجد مترجم لن تفعل ذلك.

وأو، إذا كنت حقا حقا أن تفعل ذلك، حاول (الفراغ *) صحيح. ثم غسل اليدين.

وreinterpret_cast هو فكرة . أخبرنا المزيد عن المشكلة التي نحاول حلها، وربما سوف نجد حلا دون اللجوء إلى إعادة تفسير. لماذا تريد تحويله منطقي بها باطل *؟

والمترجم الوحيد الذي قد أن يشكو هذا هو دول مجلس التعاون الخليجي (GCC مينغو مع 3.4.5) - ولست متأكدا لماذا. ويبدو هذا المعيار لتشير بوضوح إلى ذلك مسموحا به:

<اقتباس فقرة>   

و3.9.1 أنواع الأساسية

     

...

     

وأنواع منطقي، شار، wchar_t، و   وقعت وأنواع صحيحا غير موقعة هي   تسمى مجتمعة أنواع متكاملة.

     

و5.2.10 إعادة تفسير المدلى بها:

     

...

     

وقيمة من نوع لا يتجزأ أو   نوع التعداد يمكن أن يكون صريحا   تحويلها إلى المؤشر.

وقال ذلك، monjardin في الحل استخدام reinterpret_cast<void *> (static_cast<int> (true)) أو reinterpret_cast<void *> (1) هي الحلول المعقولة.

وأنه فشل بسبب المدلى بها لا معنى له - كنت تأخذ منطقية حقيقية القيمة / الزائفة، وطرح compilre لتفسير ذلك على أنه مؤشر، الذي بعبارات صريحة هو موقع الذاكرة. وهما تخلخل حتى يتصل بها عن بعد.

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

في بعض الحالات، فمن المرغوب فيه جدا أن يكون المترجم تحذير أو خطأ على كود مثل reinterpret_cast<void*>(true)، على الرغم من أن هذا الرمز هو على ما يبدو C ++ القانوني. على سبيل المثال، فإنه يساعد في ترقية إلى منصات 64 بت.

وصب مؤشر 64 بت إلى نوع لا يتجزأ أصغر من مؤشر (مثل int أو bool) وغالبا ما يكون علة: كنت اقتطاع قيمة المؤشر ل. وعلاوة على ذلك، لا يبدو أن مواصفات C ++ لضمان أن تحصل يمكن أن يلقي مباشرة مؤشر إلى نوع لا يتجزأ أصغر (التشديد مضاف):

<اقتباس فقرة>   

و5.2.10.4. مؤشر يمكن تحويلها صراحة إلى أي نوع لا يتجزأ <م> كبيرة بما يكفي للسيطرة عليه . وظيفة رسم الخرائط هو تعريف التنفيذ.

وبالمثل، صب نوع لا يتجزأ أصغر إلى مؤشر 64 بت (كما هو الحال مع reinterpret_cast<void*>(true)) وغالبا ما يكون علة أيضا: المترجم له لملء بت المؤشر في أعلى بشيء. يفعل صفر ملء أو تسجيل الدخول تمديد؟ إلا إذا كنت كتابة التعليمات البرمجية الخاصة بالنظام الأساسي على مستوى منخفض لتعيين الذاكرة I / O وصول أو DMA، وعادة ما كنت لا تريد أن تفعل ذلك على الإطلاق، إلا إذا كنت تفعل شيئا hacky (مثل حشو منطقية إلى مؤشر ). ولكن مواصفات C ++ لا يبدو أن أقول الكثير عن هذه الحالة غير أن والمعرفة من قبل التنفيذ (حاشية حذفت) ما يلي:

<اقتباس فقرة>   

و5.2.10.5. قيمة من نوع لا يتجزأ أو نوع التعداد يمكن تحويلها صراحة إلى مؤشر. *

     

ومؤشر تحويلها إلى عدد صحيح من حجم كاف (إن وجدت مثل هذه موجود على التنفيذ) والعودة إلى نفس نوع المؤشر سيكون لها قيمتها الأصلية. تعيينات بين المؤشرات والأعداد الصحيحة هي إلا تعريف التنفيذ.

وmonjardin reinterpret_cast<void*>(static_cast<int>(true)) المقترحة. إذا كان أصل الخطأ عدم تطابق بين حجم نوع لا يتجزأ وحجم المؤشر، ثم هذا سوف تعمل على معظم منصات 32 بت (على حد سواء حيث int وvoid* هي 32 بت) لكنه يفشل في معظم منصات 64 بت (حيث int هو 32 بت وvoid* هو 64 بت). في هذه الحالة، لتحل محل int في هذا التعبير مع رمية الحجم نوع عدد صحيح مثل uintptr_t أو DWORD_PTR (في ويندوز) يجب أن تعمل، منذ يسمح صحيحة التحويلات بين bool ومؤشر الحجم، وهكذا هي التحويلات بين الأعداد الصحيحة، مؤشر الحجم و المؤشرات.

والإصدارات اللاحقة من دول مجلس التعاون الخليجي وفيما يلي محذرا من قمع خيارات ، ولكن ليس لC ++ :

<اقتباس فقرة>   

و-Wno-INT-لمؤشر الصب (C والهدف-C فقط)
  قمع تحذيرات من يلقي إلى نوع مؤشر عدد صحيح من حجم مختلف.

     

و-Wno-المؤشر-إلى كثافة العمليات الصب (C والهدف-C فقط)
  قمع تحذيرات من يلقي من مؤشر إلى نوع عدد صحيح من حجم مختلف.

scroll top