هل مستوى الولاية وهو lvalue إلى rvalue تحويل المتغير المؤشر عند تطبيق المراوغة?

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

سؤال

TL;DR

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

int* ptr;
*ptr = 0;

لا *ptr تتطلب lvalue إلى rvalue التحويل من ptr قبل تطبيق المراوغة?

المعيار يشمل موضوع lvalue إلى rvalue في العديد من الأماكن ولكن لا يبدو أن تحديد ما يكفي من المعلومات لتحديد ما إذا كان * المشغل تتطلب مثل هذا التحويل.

التفاصيل

على lvalue إلى rvalue التحويل يتم تغطيتها في N3485 في القسم 4.1 Lvalue إلى rvalue التحويل الفقرة 1 و يقول (التشديد من الألغام تسير إلى الأمام):

أ glvalue (3.10) غير دالة غير صفيف نوع T يمكن تحويلها إلى prvalue.53 إذا كان T هو نوع غير مكتملة, برنامج يتطلب هذا التحويل هو سوء تشكيلها.إذا كان الكائن الذي glvalue يشير ليست كائن من نوع T وليس كائن من نوع المستمدة من T ، أو إذا كان الكائن هو غير مهيأ, برنامج يتطلب هذا التحويل لديه السلوك غير معرف.[...]

حتى لا *ptr = 0; يتطلب هذا التحويل?

إذا ذهبنا إلى القسم 4 الفقرة 1 يقول:

[...]معيار تحويل تسلسل سيتم تطبيقها على التعبير إذا لزم الأمر ليتم تحويله إلى الوجهة المطلوبة نوع.

حتى متى ضروري?إذا نظرنا في القسم 5 التعبيرات على lvalue إلى rvalue التحويل المذكورة في الفقرة 9 الذي يقول:

كلما glvalue التعبير يبدو كما المعامل من المشغل التي يتوقع prvalue لهذا المعامل ، lvalue إلى rvalue (4.1), مجموعة إلى مؤشر (4.2) ، أو وظيفة إلى مؤشر (4.3) القياسية التحويلات يتم تطبيق لتحويل تعبير إلى prvalue.[...]

و الفقرة 11 الذي يقول:

في بعض السياقات تعبير يظهر فقط على آثارها الجانبية.مثل هذا التعبير يسمى تجاهل قيمة التعبير.[ ... ] ، lvalue إلى rvalue التحويل (4.1) يتم تطبيقها إذا و فقط إذا كان التعبير هو lvalue المتقلبة-مؤهل نوع و هو واحد من التالية [...]

ولا الفقرة يبدو أن تطبيق هذا نموذج التعليمات البرمجية ، 5.3.1 استخدام عوامل التشغيل الأحادية الفقرة 1 يقول:

فإن الأحادية * مشغل ينفذ المراوغة:التعبير الذي هو تطبيق يجب أن يكون مؤشر إلى كائن من نوع ، أو مؤشر إلى وظيفة نوع والنتيجة هي lvalue مشيرا إلى كائن أو وظيفة والتي التعبير نقاط.إذا كان نوع من التعبير هو "مؤشر ر" نوع من النتيجة "T." [ ملاحظة:المراوغة من خلال مؤشر إلى نوع غير مكتملة (بخلاف السيرة الذاتية الفراغ) هو صالح.على lvalue التي تم الحصول عليها وبالتالي يمكن استخدامها في سبل محدودة (تهيئة المرجعية ، على سبيل المثال) ؛ هذا lvalue لا يجب تحويلها إلى prvalue ، انظر 4.1.—end note ]

لا يبدو أن تتطلب القيمة المؤشر وأنا لا أرى أي شروط التحويل من المؤشر ها أنا في عداد المفقودين شيئا ؟

لماذا نهتم ؟

لقد رأيت جوابا والتعليقات في الأسئلة الأخرى التي تدعي استخدام غير مهيأ مؤشر غير معرف السلوك بسبب الحاجة lvalue إلى rvalue التحويل من ptr قبل تطبيق المراوغة.على سبيل المثال: حيث يفعل بالضبط C++ القياسية أقول dereferencing غير مهيأ مؤشر غير معرف السلوك ؟ يجعل هذه الحجة وأنا لا يمكن التوفيق بين الحجة مع ما هو وارد في أي مشروع الإصدارات القياسية.منذ أن رأيت هذا عدة مرات أردت التوضيح.

الفعلية دليلا على السلوك غير معرف ليست مهمة منذ وكما ذكرت في ربط السؤال أعلاه لدينا الآخرين طريقة للوصول إلى السلوك غير معرف.

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

المحلول 2

لقد حولت تحديث القسم في سؤالي جوابا لأن في هذه النقطة يبدو أن الإجابة كانت غير مرضية واحدة هذا السؤال بلا إجابة:

dyp وأشار لي إلى اثنين من المواضيع ذات الصلة التي تغطي مشابهة جدا الأرض:

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

هناك عدد قليل من الحس حجج على القصد من المعيار.يمكن للمرء أن يجادل Logicially ، المعامل هو prvalue إذا كانت العملية تتطلب استخدام قيمة هذا المعامل.حجة أخرى هي أنه إذا كنا ننظر إلى الوراء إلى C99 مشروع القياسية يقول وهو lvalue إلى rvalue يتم التحويل بشكل افتراضي و الاستثناءات لاحظت.الفرع ذي الصلة من مشروع C99 المعيار هو 6.3.2.1 Lvalues, صفائف, وظيفة المميزان الفقرة 2 الذي يقول:

باستثناء عندما يكون المعامل sizeof المشغل ، الأحادية & المشغل ، ++ مشغل و مشغل أو المعامل الأيسر من .المشغل أو مهمة المشغل ، وهو lvalue أن لا يكون نوع مصفوفة يتم تحويلها إلى القيمة المخزنة في الكائن المعين (و لم يعد lvalue).[...]

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

كما حاولت أن أوضح الدليل على غير معرفة السلوك كان أقل أهمية من توضيح ما إذا كان lvalue إلى rvalue التحويل مكلفة.إذا أردنا أن نثبت السلوك غير معرف لدينا النهج البديلة.جيري نهج الحس السليم واحدة في هذا المراوغة يتطلب أن التعبير يكون مؤشر إلى كائن أو وظيفة غير محددة القيمة فقط عن طريق الصدفة نقطة وثلاجة. في عام مشروع C++ القياسية لا تعطي بيان صريح القول استخدام غير محدد القيمة غير محددة ، على عكس C99 مشروع القياسية في C++11 و العودة القياسية لا تعطي بيان صريح القول استخدام غير محدد القيمة غير محددة.باستثناء التكرار وبالتالي المؤشرات لدينا مفهوم المفرد القيمة و قيل لنا في القسم 24.2.1 أن:

[...][ مثال:بعد إعلان غير مهيأ مؤشر س (كما هو الحال مع int* x;), x يجب أن يكون دائما يفترض أن يكون المفرد قيمة المؤشر.المثال ] [...] Dereferenceable القيم هي دائما غير المفرد.

و:

غير مكرر غير مكرر التي قد تكون المفرد.268

و الحاشية 268 يقول:

هذا التعريف ينطبق على المؤشرات منذ مؤشرات التكرار.تأثير dereferencing مكرر التي تم إبطالها هو غير معروف.

في C++1y اللغة التغييرات لدينا بيان صريح من قيمة وسيطة غير معروف مع بعض الاستثناءات الضيقة.

نصائح أخرى

أعتقد أنك تقترب من هذا بدلا من زاوية مائلة ، إذا جاز التعبير.وفقا ل §5.3.1/1:

فإن الأحادية * مشغل ينفذ المراوغة:التعبير الذي يتم تطبيقه يجب أن يكون مؤشر إلى نوع الكائن أو مؤشر إلى نوع وظيفة والنتيجة هي lvalue مشيرا إلى كائن أو وظيفة والتي التعبير نقاط.إذا كان نوع من التعبير هو "مؤشر ر" نوع والنتيجة هي "تي."

على الرغم من أن هذا لا يتحدث عن lvalue إلى rvalue التحويل ، فإنه يتطلب أن التعبير يكون مؤشر إلى كائن أو وظيفة.غير مهيأ المؤشر لن (ربما باستثناء طريق الصدفة) يكون أي شيء من هذا القبيل حتى محاولة dereferencing يعطي السلوك غير معرف.

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