ما الذي يجب أن يعيده الرئيسي() في C و C++؟




return-value main (16)

عودة 0 على النجاح وعدم الصفر للخطأ. هذا هو المعيار المستخدم من قبل UNIX و DOS script لمعرفة ما حدث مع برنامجك.


Keep in mind that,even though you're returning an int, some OSes (Windows) truncate the returned value to a single byte (0-255).


If you really have issues related to efficiency of returning an integer from a process, you should probably avoid to call that process so many times that this return value becomes an issue.

If you are doing this (call a process so many times), you should find a way to put your logic directly inside the caller, or in a DLL file, without allocate a specific process for each call; the multiple process allocations bring you the relevant efficiency problem in this case.

In detail, if you only want to know if returning 0 is more or less efficient than returning 1, it could depend from the compiler in some cases, but generically, assuming they are read from the same source (local, field, constant, embedded in the code, function result, etc.) it requires exactly the same number of clock cycles.


The return value of main() shows how the program exited. If the return value is zero it means that the execution was successful while any non-zero value will represent that something went bad in the execution.


In C++ the main function should be declared as int main() and not void main() as the compiler then throws an error in the case of void main. The main function can take any number of arguments like int main(int k,int l,int arr[]) or int main(void).

#include <iostream>
using namespace std;

int main(void) {
    // your code goes here
    cout<<"a";
    return 0;
}

انتاج:

Success #stdin #stdout 0s 4416KB
a

Coming to the return part it should return only 0 else the compiler throws an error. for example if you return 1,you will get the desired output but it also throws a runtime error.

مثال

#include <iostream>
using namespace std;

int main(int k,float m,char g, int arr[]) {
    // your code goes here
    k=0;
    cout<<k;
    g='a';
    cout<<g;
    cout<<"a";
    return 1;
}

انتاج:

Runtime error   #stdin #stdout 0s 4448KB
0aa

The return value can be used by the operating system to check how the program was closed.

Return value 0 usually means OK in most operating systems (the ones I can think of anyway).

It also can be checked when you call a process yourself, and see if the program exited and finished properly.

It's NOT just a programming convention.


main() in C89 and K&R C unspecified return types default to 'int`.

return 1? return 0?
  1. If you do not write a return statement in int main() , the closing { will return 0 by default.

  2. return 0 or return 1 will be received by the parent process. In a shell it goes into a shell variable, and if you are running your program form a shell and not using that variable then you need not worry about the return value of main() .

See How can I get what my main function has returned? .

$ ./a.out
$ echo $?

This way you can see that it is the variable $? which receives the least significant byte of the return value of main() .

In Unix and DOS scripting, return 0 on success and non-zero for error are usually returned. This is the standard used by Unix and DOS scripting to find out what happened with your program and controlling the whole flow.


معيار C - البيئة المستضافة

بالنسبة إلى بيئة مستضافة (هذا هو الوضع الطبيعي) ، فإن معيار C11 (ISO / IEC 9899: 2011) يقول:

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

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

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

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

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

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

إذا تم الإعلان عنها ، يجب أن تتوافق المعلمات مع الوظيفة الرئيسية مع القيود التالية:

  • يجب أن تكون قيمة argc غير سالبة.
  • argv[argc] يجب أن يكون مؤشر null.
  • إذا كانت قيمة argc أكبر من الصفر ، يجب أن يحتوي أعضاء الصفيف argv[0] خلال argv[argc-1] على مؤشرات إلى سلاسل ، والتي تعطى قيمًا محددة للتنفيذ بواسطة بيئة المضيف قبل بدء تشغيل البرنامج. يتمثل الهدف في توفير معلومات البرنامج التي تم تحديدها قبل بدء تشغيل البرنامج من مكان آخر في البيئة المستضافة. إذا كانت بيئة المضيف غير قادرة على توفير سلاسل بأحرف كبيرة وكبيرة على حد سواء ، يجب أن يضمن التنفيذ استلام السلاسل الصغيرة.
  • إذا كانت قيمة argc أكبر من الصفر ، تمثل السلسلة المشار إليها بواسطة argv[0] اسم البرنامج ؛ يجب أن يكون argv[0][0] الحرف الفارغ إذا كان اسم البرنامج غير متوفر من بيئة المضيف. إذا كانت قيمة argc أكبر من واحد ، فإن السلاسل المشار إليها بواسطة argv[1] خلال argv[argc-1] تمثل معلمات البرنامج.
  • يجب أن تكون المعلمات argc و argv والسلاسل المشار إليها بواسطة صفيف argv قابلة للتعديل من قبل البرنامج ، والاحتفاظ بالقيم المخزنة الأخيرة بين بدء البرنامج وإنهاء البرنامج.

10) وهكذا ، يمكن استبدال int بإسم typedef المعرّف كـ int ، أو يمكن كتابة نوع argv كـ char **argv ، وهكذا.

إنهاء البرنامج في C99 أو C11

يتم إرسال القيمة التي يتم إرجاعها من main() إلى "البيئة" بطريقة محددة بالتنفيذ.

5.1.2.2.3 إنهاء البرنامج

1 إذا كان نوع الإرجاع للوظيفة main هو نوع متوافق مع int ، فإن المكافأة من الاستدعاء الأولي إلى الوظيفة main تعادل استدعاء وظيفة exit بالقيمة التي main الدالة main كوسيطة لها ؛ 11) الوصول إلى } الذي ينهي الدالة main بإرجاع قيمة 0. إذا كان نوع الإرجاع غير متوافق مع int ، فإن حالة الإنهاء التي يتم إرجاعها إلى بيئة المضيف غير محددة.

11) وفقاً للفقرة 6.2.4 ، تنتهي أعمار الأشياء ذات مدة التخزين التلقائي المعلن عنها بشكل main في الحالة الأولى ، حتى عندما لا تكون موجودة في الحالة الأخيرة.

لاحظ أنه تم تفويض 0 كـ "success". يمكنك استخدام EXIT_FAILURE و EXIT_SUCCESS من <stdlib.h> إذا كنت تفضل ذلك ، ولكن 0 تم تأسيسها بشكل جيد ، وكذلك 1. انظر أيضًا Exit codes Exit رموز أكبر من 255 - ممكن؟ .

في C89 (ومن ثم في Microsoft C) ، لا يوجد بيان حول ما يحدث في حالة إرجاع الدالة main() ولكنها لا تحدد قيمة إرجاع؛ لذلك يؤدي إلى سلوك غير معروف.

7.22.4.4 وظيفة exit

Finally5 وأخيرا ، يتم إرجاع التحكم إلى البيئة المضيفة. إذا كانت قيمة status صفرًا أو EXIT_SUCCESS ، يتم إرجاع نموذج معرفة بالتنفيذ للحالة الناجحة . إذا كانت قيمة status EXIT_FAILURE ، يتم إرجاع نموذج المعرفة من إنهاء الحالة غير ناجحة . وإلا فإن الحالة التي يتم إرجاعها هي محددة بالتنفيذ.

معيار C ++ - البيئة المستضافة

يقول معيار C ++ 11 (ISO / IEC 14882: 2011):

3.6.1 الوظيفة الرئيسية [basic.start.main]

A1 يجب أن يحتوي البرنامج على وظيفة عالمية تسمى main ، وهي البداية المعينة للبرنامج. [...]

An2 يجب ألا يسبق التنفيذ الوظيفة الرئيسية. هذه الوظيفة لن تكون محملة بشكل زائد. يجب أن يحتوي على نوع إرجاع من int ، ولكن بخلاف ذلك يتم تعريف نوعه. يجب أن تسمح جميع عمليات التنفيذ بالتعريفات الرئيسية التالية:

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

و

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

يجب أن يكون argc في الصيغة الأخيرة هو عدد الوسيطات التي تم تمريرها إلى البرنامج من البيئة التي يتم تشغيل البرنامج فيها. إذا كانت argc غير صفرية ، فيجب أن يتم توفير هذه الوسيطات في argv[0] خلال argv[argc-1] كمؤشرات للأحرف الأولية لسلسلة متعددة البتات المنتهية بقيمة null (NTMBSs) (17.5.2.1.4.2) ويجب أن تكون argv[0] المؤشر إلى الحرف الأولي لـ NTMBS الذي يمثل الاسم المستخدم لاستدعاء البرنامج أو "" . يجب أن تكون قيمة argc غير سالبة. يجب أن تكون قيمة argv[argc] 0. [ملاحظة: يوصى بإضافة أية معلمات إضافية (اختيارية) بعد argv . لاحظ مذكرة

¶3 لا يجوز استخدام الوظيفة main في البرنامج. الربط (3.5) main هو محدد بالتنفيذ. [...]

A5 بيان الإرجاع الرئيسي له تأثير ترك الوظيفة الرئيسية (تدمير أي كائنات مع مدة التخزين التلقائي) واستدعاء std::exit مع قيمة الإرجاع كوسيطة. إذا بلغ التحكم نهاية الطرف الرئيسي دون مواجهة عبارة إرجاع ، يكون التأثير هو التنفيذ

return 0;

ينص معيار C ++ صراحةً على أنه "يجب أن يكون لـ [الدالة الرئيسية] نوع إرجاع من نوع int ، ولكن بخلاف ذلك يتم تعريف نوعه" ، ويتطلب نفس التوقيعين مثل المعيار C المطلوب دعمه كخيارات. وبالتالي ، لا يسمح معيار "C ++" بشكل مباشر من قبل معيار C ++ ، على الرغم من أنه لا يوجد شيء يمكنه فعله لإيقاف التنفيذ غير القياسي الذي يسمح بالبدائل. لاحظ أن C ++ تمنع المستخدم من الاتصال main (ولكن لا يستخدم المعيار C).

توجد فقرة من § §6.5 البدء والانهاء في معيار C ++ 11 مماثلة للفقرة من § 7.2.2.4.4 وظيفة exit في معيار C11 (المذكورة أعلاه) ، وبصرف النظر عن الحاشية (التي تقوم ببساطة بتوثيق EXIT_SUCCESS و يتم تعريف EXIT_FAILURE في <cstdlib> ).

المعيار C - الامتداد المشترك

كلاسيكياً ، تدعم أنظمة Unix صيغة ثالثة:

int main(int argc, char **argv, char **envp) { ... }

الوسيطة الثالثة هي قائمة خالية من المؤشرات التي يتم إنهاؤها إلى سلاسل ، كل منها عبارة عن متغير بيئة له اسم ، وعلامة يساوي ، وقيمة (ربما فارغة). إذا كنت لا تستخدم هذا ، فلا يزال بإمكانك الوصول إلى البيئة عبر " extern char **environ; ". لفترة طويلة ، لم يكن يحتوي على رأس إعلان ، ولكن معيار POSIX 2008 يتطلب الآن أن يتم الإعلان عنه في <unistd.h> .

هذا معترف به في المعيار C باعتباره امتدادًا مشتركًا موثقًا في الملحق ياء:

J.5.1 حجج البيئة

In1 في بيئة مستضافة ، تستلم الدالة الرئيسية وسيطة ثالثة ، char *envp[] ، والتي تشير إلى صفائف نهاية خالية من المؤشرات إلى char ، يشير كل منها إلى سلسلة توفر معلومات حول البيئة لهذا التنفيذ. من البرنامج (5.1.2.2.1).

مايكروسوفت ج

برنامج Microsoft VS 2010 هو مثير للاهتمام. موقع الويب يقول:

بناء جملة الإعلان الرئيسي

 int main();

أو اختياريًا

int main(int argc, char *argv[], char *envp[]);

بدلاً من ذلك ، يمكن الإعلان عن الدالات main و wmain (بدون قيمة إرجاع). إذا قمت بتعريف main أو wmain باطل ، لا يمكنك إرجاع رمز إنهاء إلى عملية الأصل أو نظام التشغيل باستخدام عبارة return. لإرجاع رمز إنهاء عند الإعلان عن main أو wmain ، يجب استخدام وظيفة exit .

ليس من الواضح بالنسبة لي ما يحدث (ما هو رمز الخروج الذي يتم إرجاعه إلى الوالد أو نظام التشغيل) عندما يخرج أحد البرامج التي تحتوي على void main() - ويكون موقع الويب MS صامتًا أيضًا.

من المثير للاهتمام ، لا يصف MS النسخة ثنائية الحجة من main() التي تتطلب معايير C و C ++. يصف فقط نموذج الوسيطة الثلاث حيث تكون الوسيطة الثالثة char **envp ، مؤشر إلى قائمة متغيرات البيئة.

تسرد صفحة Microsoft أيضًا بعض البدائل الأخرى - wmain() التي تأخذ سلاسل أحرف كبيرة ، وبعضها الآخر.

لا يقوم الإصدار Microsoft Visual Studio 2005 من هذه الصفحة بإدراج void main() كبديل. versions من Microsoft Visual Studio 2008 فصاعدا.

معيار C - بيئة قائمة بذاتها

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

5.1.2 بيئات التنفيذ

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

5.1.2.1 بيئة قائمة بذاتها

في بيئة قائمة بذاتها (حيث يمكن تنفيذ برنامج C دون أي فائدة من نظام التشغيل) ، يكون اسم ونوع الوظيفة التي يتم استدعاؤها عند بدء تشغيل البرنامج محددًا. إن أي مرافق مكتبة متاحة لبرنامج قائم بذاته ، بخلاف المجموعة الدنيا التي يتطلبها البند 4 ، يتم تعريفها بالتنفيذ.

يتم تحديد تأثير إنهاء البرنامج في بيئة قائمة بذاتها.

تشير الإشارة إلى البند 4 من المطابقة إلى ما يلي:

A5 يجب أن يستخدم البرنامج المطابق بدقة فقط ميزات اللغة والمكتبة المحددة في هذه المواصفة القياسية الدولية. 3) يجب ألا ينتج إخراج يعتمد على أي سلوك غير محدد أو غير محدد أو محدد من قبل التنفيذ ، ويجب ألا يتجاوز أي حد أدنى للتنفيذ.

¶6 يتم استيفاء شكلين من التطبيق المطابق و قائما بذاته . يجب أن يقبل التنفيذ المستضاف المطابق أي برنامج مطابق تمامًا. يجب أن يتطابق تطبيق قائم بذاته متوافق مع أي برنامج مطابق تمامًا حيث يقتصر استخدام الميزات المحددة في بند المكتبة (البند 7) على محتويات الرؤوس القياسية <float.h> ، <iso646.h> ، <limits.h> <float.h> <limits.h> و <stdalign.h> و <stdarg.h> و <stdbool.h> و <stddef.h> و <stdint.h> و <stdnoreturn.h> . قد يكون للتطبيق المطابق امتدادات (بما في ذلك وظائف المكتبة الإضافية) ، شريطة ألا يغير سلوك أي برنامج مطابق تمامًا. 4)

A7 البرنامج المطابق هو أحد البرامج المقبولة للتنفيذ المطابق. 5)

3) يمكن للبرنامج المطابق بدقة أن يستخدم ميزات مشروطة (انظر 6.10.8.3) بشرط أن يكون الاستخدام محميًا بتوجيه معالجة شرطية تضمين مناسب باستخدام الماكرو ذي الصلة. فمثلا:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4) وهذا يعني أن التطبيق المطابق لا يحتفظ بمعرّفات غير تلك المحددة صراحة في هذه المواصفة القياسية الدولية.

5) تهدف البرامج المطابقة بدقة إلى أن تكون محمولة إلى أقصى حد بين التطبيقات المطابقة. قد تعتمد البرامج المطابقة على ميزات غير محمولة للتنفيذ المطابق.

من الملاحظ أن العنوان الوحيد المطلوب من بيئة قائمة بذاتها هي التي تحدد أي وظائف هي <stdarg.h> (وحتى تلك قد تكون - وغالباً ما تكون - وحدات ماكرو فقط).

معيار C ++ - بيئة قائمة بذاتها

تماماً كما يتعرف معيار C على البيئة المستضافة والقائمة بذاتها ، كذلك ينطبق معيار C ++. (اقتباسات من ISO / IEC 14882: 2011.)

1.4 الامتثال للتنفيذ [intro.compliance]

are 7 يتم تعريف نوعين من التطبيقات: تطبيق مستضاف وتطبيق قائم بذاته . بالنسبة للتنفيذ المستضاف ، تحدد هذه المواصفة القياسية الدولية مجموعة المكتبات المتاحة. تطبيق قائم بذاته هو التنفيذ الذي يمكن تنفيذه دون الاستفادة من نظام التشغيل ، وله مجموعة محددة من التطبيقات التي تتضمن مكتبات معينة تدعم اللغات (17.6.1.3).

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

9- يجب أن يتضمن كل تنفيذ وثائق تحدد جميع التركيبات المدعومة شرطا والتي لا تدعمها وتحدد جميع الخصائص الخاصة بالموقع. 3

3) تحدد هذه الوثائق أيضًا السلوك المحدد للتنفيذ ؛ انظر 1.9.

17.6.1.3 التطبيقات القائمة بذاتها [الامتثال]

يتم تعريف نوعين من تطبيقات: استضافتها و قائما بذاته (1.4). بالنسبة للتنفيذ المستضاف ، تصف هذه المواصفة القياسية الدولية مجموعة الرؤوس المتاحة.

يحتوي تطبيق قائم بذاته على مجموعة من الرؤوس المحددة بالتنفيذ. يجب أن تتضمن هذه المجموعة على الأقل العناوين الموضحة في الجدول 16.

يجب أن تعلن النسخة المرفقة من الرأس <cstdlib> عن الوظائف التي تم atexit ، at_quick_exit ، at_quick_exit ، exit ، و quick_exit (18.5) على quick_exit . يجب أن تستوفي الرؤوس الأخرى المدرجة في هذا الجدول نفس المتطلبات الخاصة بالتنفيذ المستضاف.

جدول 16 - رؤوس C ++ للتطبيقات القائمة بذاتها

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

ماذا عن استخدام int main() في C؟

يوضح المعيار §1.1.2.2.1 من المعيار C11 الرمز المفضل - int main(void) - ولكن هناك أيضًا مثالان في المعيار الذي يظهر int main() : §6.5.3.4 -8 و §6.7.6.3 ¶20 . الآن ، من المهم ملاحظة أن الأمثلة ليست "معيارية" ؛ هم فقط توضيحية. إذا كان هناك أخطاء في الأمثلة ، فإنها لا تؤثر بشكل مباشر على النص الرئيسي للمعيار. ومع ذلك ، فهي تشير بقوة إلى السلوك المتوقع ، لذلك إذا كان المعيار يشتمل على int main() في مثال ، فإنه يشير إلى أن int main() غير محظور ، حتى إذا لم يكن هذا هو الترميز المفضل.

_Alignof مشغلات _Alignof و

...

EX8 EXAMPLE 3 في هذا المثال ، يتم حساب حجم صفيف الطول المتغير ويتم إعادته من دالة:

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}

يبدو أن الإجابة المقبولة مستهدفة لـ C ++ ، لذلك أعتقد أنني سأضيف إجابة تتعلق بـ C ، وهذا يختلف في بعض الطرق.

ISO / IEC 9899: 1989 (C90):

main() يجب أن يُعلن إما:

int main(void)
int main(int argc, char **argv)

أو ما يعادلها. على سبيل المثال ، int main(int argc, char *argv[]) يساوي الثاني. علاوة على ذلك ، يمكن حذف نوع الإرجاع الداخلي نظرًا لأنه افتراضي.

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

يحدد المعيار 3 قيم للعائدات التي تتوافق تمامًا (أي لا تعتمد على السلوك المحدد للتنفيذ): 0 و EXIT_SUCCESS لإنهاء ناجح ، و EXIT_FAILURE لإنهاء غير ناجح. أي قيم أخرى غير قياسية ويتم تعريف التنفيذ. main() يجب أن يكون لديك بيان return صريح في النهاية لتجنب السلوك غير المعرّف.

وأخيرا ، لا يوجد شيء خاطئ من وجهة نظر المعايير مع استدعاء main() من البرنامج.

ISO / IEC 9899: 1999 (C99):

بالنسبة لـ C99 ، كل شيء هو نفسه كما هو مذكور أعلاه باستثناء:

  • قد لا يتم حذف نوع الإرجاع الداخلي.
  • يمكنك حذف بيان الإرجاع من main() . إذا قمت بذلك ، وتم main() ، يكون هناك return 0 ضمنية return 0 .

I was under the impression that standard specifies that main doesn't need a return value as a successful return was OS based (zero in one could be either a success or a failure in another), therefore the absence of return was a cue for the compiler to insert the successful return itself.

However I usually return 0.


أعتقد أن main() يجب أن تعود إما EXIT_SUCCESS أو EXIT_FAILURE . يتم تعريف في stdlib.h


Omit return 0

When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main .

Note: when I make this suggestion, it's almost invariably followed by one of two kinds of comments: "I didn't know that." or "That's bad advice!" My rationale is that it's safe and useful to rely on compiler behavior explicitly supported by the standard. For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:

[...] a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.

For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:

If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to "it looks weird" . If, like me, you're curious about the rationale for the change to the C standard read this question . Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.

So I advocate omitting it; others disagree (often vehemently!) In any case, if you encounter code that omits it, you'll know that it's explicitly supported by the standard and you'll know what it means.


يجب أن تشير قيمة الإرجاع main إلى كيفية إنهاء البرنامج. يتم تمثيل المخرج العادي عادة بقيمة 0 رجوع من main . عادة ما يتم الإشارة إلى الإنهاء غير الطبيعي بعائد غير صفري ، ولكن لا يوجد معيار لكيفية تفسير الرموز غير الصفرية. كما لوحظ من قبل الآخرين ، محظور صراحة void main() بشكل صريح من قبل معيار C ++ ولا ينبغي أن تستخدم. التوقيعات main C ++ الصالحة هي:

int main()

و

int main(int argc, char* argv[])

وهو ما يعادل

int main(int argc, char** argv)

تجدر الإشارة أيضًا إلى أنه في C ++ ، يمكن ترك int main() بدون قيمة إرجاع عندها تكون القيمة الافتراضية لعودة 0. وهذا صحيح أيضًا مع برنامج C99. ما إذا كان يجب حذف 0 أو لا يكون مفتوحًا للنقاش. نطاق التوقيعات الرئيسية لبرنامج C الصالح هو أكبر من ذلك بكثير.

أيضا ، الكفاءة ليست مشكلة مع الوظيفة main . يمكن إدخاله وتركه مرة واحدة فقط (بمناسبة بدء البرنامج وإنهائه) وفقًا لمعيار C ++. بالنسبة لـ C ، الحالة مختلفة ويُسمح بإعادة الإدخال main() ، ولكن ربما ينبغي تجنبها.


Returning 0 should tell the programmer that the program has successfully finished the job.


What is the correct (most efficient) way to define the main() function in C and C++ — int main() or void main() — and why?

Those words "(most efficient)" don't change the question. Unless you're in a freestanding environment, there is one universally correct way to declare main() , and that's as returning int.

What should main() return in C and C++?

It's not what should main() return, it's what does main() return. main() is, of course, a function that someone else calls. You don't have any control over the code that calls main() . Therefore, you must declare main() with a type-correct signature to match its caller. You simply don't have any choice in the matter. You don't have to ask yourself what's more or less efficient, or what's better or worse style, or anything like that, because the answer is already perfectly well defined, for you, by the C and C+ standards. Just follow them.

If int main() then return 1 or return 0?

0 for success, nonzero for failure. Again, not something you need to (or get to) pick: it's defined by the interface you're supposed to be conforming to.


What to return depends on what you want to do with the executable. For example if you are using your program with a command line shell, then you need to return 0 for a success and a non zero for failure. Then you would be able to use the program in shells with conditional processing depending on the outcome of your code. Also you can assign any nonzero value as per your interpretation, for example for critical errors different program exit points could terminate a program with different exit values , and which is available to the calling shell which can decide what to do by inspecting the value returned. If the code is not intended for use with shells and the returned value does not bother anybody then it might be omitted. I personally use the signature int main (void) { .. return 0; .. }





return-type