هل يمكن أن تحتوي وسيطات التوقيع الرئيسي في C++ على المؤهلات غير الموقعة والثابتة؟[ينسخ]

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

  •  06-07-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

المعيار ينص صراحة على ذلك main لديه توقيعين صالحين (أي مضمونين للعمل)؛يسمى:

int main();
int main(int, char*[]);

سؤالي بسيط، هل سيكون شيء مثل ما يلي قانونيًا؟

int main(const unsigned int, const char* const* argv);

اختباراتي تقول "نعم"، لكنني غير متأكد من الإجابة لأنني لا أحمل الزائد main عن طريق تغيير int ل unsigned int وكذلك المستوى غير الأعلى const-ness من argv؟إذا كنت كذلك، فمن الواضح أن هذا محظور.

إذن، هل هذه التعديلات مضمونة للعمل على مترجم مطابق للمعايير؟

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

المحلول

يقول معيار C++ 98 في القسم 3.6.1 الفقرة 2

يجب ألا يحدد التنفيذ الوظيفة الرئيسية مسبقًا.لا يجوز تحميل هذه الوظيفة بشكل زائد.يجب أن يكون لها نوع الإرجاع من النوع int, ، ولكن بخلاف ذلك فإن نوعه محدد بالتنفيذ.يجب أن تسمح جميع التطبيقات بالتعريفين التاليين لـ main: int main() و int main(int argc, char* argv[])

لذلك لا يتم تكليفه بالمعيار الذي تقبله البيئة main مقبول ولكنه جائز.


ولأن هذا يتم الإشارة إليه كثيرًا، فإليك الفقرة السابقة التي تعفي البيئات المستقلة من أي شيء سوى توثيق سلوكها:

يجب أن يحتوي البرنامج على دالة عامة تسمى main، وهي البداية المحددة للبرنامج.يتم تعريف التنفيذ ما إذا كان البرنامج في بيئة قائما بذاته مطلوبًا لتحديد وظيفة رئيسية.[ملحوظة:في بيئة قائمة بذاتها ، يتم تحديد التنفيذ بدء التشغيل والإنهاء ؛يحتوي بدء التشغيل على تنفيذ المُنشئين لكائنات نطاق مساحة الاسم مع مدة تخزين ثابتة ؛يحتوي الإنهاء على تنفيذ المدمرات للأشياء ذات مدة التخزين الثابتة.]

نصائح أخرى

يجب عليك استخدام أحد التوقيعات المتوافقة مع المعايير لتكون متوافقًا مع المعايير.

أنا أفهم تمامًا سبب رغبتك في القيام بذلك بطريقتك.أفضل طريقة هي كتابة وظيفتك الخاصة الرئيسي عندي() أو أي شيء بالتوقيع الذي تريده وقم باستدعائه من main()، بما في ذلك الممثلين المطلوبين.

ال argv لا ينبغي أن تكون المؤشرات const char* const لأنه يسمح للبرنامج بتغيير المخازن المؤقتة.

بقدر ما أستطيع أن أرى من قراءة المعيار، أنت غير متوافق مع المعايير.لكن لا يمكنني أن أتخيل مترجمًا لن يسمح لك بالقيام بذلك.كما هو الحال في الأمر، سيستغرق الأمر المزيد من العمل من المترجم لحظر حالة الحافة على وجه التحديد والتي تكون في الغالب غير ضارة وغامضة للغاية.

قد لا يعمل هذا إذا كان المترجم يستخدم تغيير الاسم لـ main.إنها وظيفة C++ بعد كل شيء.ومن ثم، فإن الرابط سوف يبحث عن اثنين من "التشوهات" المحددة.التعريف الخاص بك سيكون له اسم مشوه آخر.

لاحظ أن main خاص (لا يتم تحميله بشكل زائد، وغير قابل للاستدعاء) وقد لا يتطلب تغيير الاسم على الإطلاق.

قد تكون غير قانوني وفقًا للمعايير، لكن معظم أوقات التشغيل لا تهتم حقًا.سوف يقومون فقط بدفع عدد صحيح لـ argc ومؤشر ل argv, ، استدع خاصتك main, ، ونأمل أن تقوم بتحليلها بشكل صحيح.لذا، في نطاق اختصاصك، فإن عبارة "مضمون للعمل" أمر قابل للنقاش لأن المُحمل لا يهتم حقًا بما أعلنته عن الوسيطات.

فإذا بني، main سيتم الاتصال به.إن كيفية تحليل الحجج أمر متروك لك.يجب أن أوضح أن هذا خاص جدًا بالمنصة، كما هو الحال مع هذا السؤال بأكمله تقريبًا.

هكذا قال، لماذا ؟

ISO/IEC 9899:TC3

القسم 5.1.2.2.1 بدء تشغيل البرنامج

تسمى الوظيفة التي يتم استدعاؤها عند بدء تشغيل البرنامج بالرئيسية.لا يعلن التنفيذ أي نموذج أولي لهذه الوظيفة.يجب تعريفه بنوع إرجاع من int وبدون معلمات:

int main(void) { /* ... */ }

أو مع معلمتين (يشار إليها هنا باسم ArgC و Argv ، على الرغم من أنه يمكن استخدام أي أسماء ، لأنها محلية في الوظيفة التي يتم الإعلان عنها):

int main(int argc, char *argv[]) { /* ... */ }

أو ما يعادله؛ 9) أو بطريقة أخرى محددة بالتنفيذ.

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