c++ - Что должно main () возвращать в C и C ++?




9 Answers

Возвращаемое значение для main должно указывать, как вышла программа. Нормальный выход обычно представлен возвращаемым значением 0 из main . Аномальный выход обычно сигнализируется ненулевым возвратом, но нет стандарта для интерпретации ненулевых кодов. Также, как отмечают другие, void main() явно запрещен стандартом C ++ и не должен использоваться. Подлинными сигнатурами C ++ являются:

int main()

а также

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

что эквивалентно

int main(int argc, char** argv)

Также стоит отметить, что в C ++ int main() может быть оставлен без возвращаемого значения, после которого по умолчанию оно возвращается 0. Это также верно и для программы C99. Нужно ли исключать return 0 или нет, открыто для обсуждения. Диапазон действительных сигнатур основных программ C намного больше.

Кроме того, эффективность не является проблемой с main функцией. Его можно вводить и оставлять один раз (обозначая начало и завершение программы) в соответствии со стандартом C ++. Для C случай отличается и повторный вход в main() разрешен, но его следует избегать.




Стандартная 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] должен быть нулевым указателем.
  • Если значение 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 функцией в качестве аргумента; 11), достигая } который завершает main функцию, возвращает значение 0. Если тип возврата несовместим с int , статус завершения, возвращаемый в среду хоста, не указан.

11) В соответствии с 6.2.4 время жизни объектов с автоматическим временем хранения, объявленным в main , закончится в первом случае, даже если они не были бы в последнем.

Обратите внимание, что 0 задается как «успех». Вы можете использовать EXIT_FAILURE и EXIT_SUCCESS из <stdlib.h> если хотите, но 0 хорошо установлено, и это значит 1. См. Также Коды выхода более 255 - возможно? ,

В C89 (и, следовательно, в Microsoft C) нет утверждения о том, что произойдет, если функция main() вернется, но не указала возвращаемое значение; поэтому он приводит к неопределенному поведению.

7.22.4.4 Функция exit

¶5 Наконец, управление возвращается в среду хоста. Если значение status равно нулю или EXIT_SUCCESS , возвращается форма завершения успешного завершения статуса. Если значением status является EXIT_FAILURE , возвращается форма безуспешного завершения status , определяемая реализацией. В противном случае возвращаемый статус определяется реализацией.

Стандартный C ++ - размещенная среда

Стандарт C ++ 11 (ISO / IEC 14882: 2011) гласит:

3.6.1 Основная функция [basic.start.main]

¶1 Программа должна содержать глобальную функцию main, которая является назначенным началом программы. [...]

¶2 Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь тип возвращаемого типа int, но в противном случае его тип определяется реализацией. Все реализации должны учитывать оба следующих определения:

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

а также

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

В последнем случае argc должно быть числом аргументов, переданных программе из среды, в которой выполняется программа. Если argc отличен от нуля, эти аргументы должны быть предоставлены в argv[0] через argv[argc-1] качестве указателей на начальные символы многобайтовых строк с нулевым завершением (NTMBS) (17.5.2.1.4.2) и argv[0] указатель на начальный символ NTMBS, который представляет имя, используемое для вызова программы или "" . Значение argc должно быть неотрицательным. Значение argv[argc] должно быть равно 0. [Примечание: рекомендуется добавлять любые дополнительные (необязательные) параметры после argv . -End note]

¶3 Функция main не должна использоваться внутри программы. Связь (3.5) main определяется реализацией. [...]

¶5 Оператор возврата в основном имеет эффект оставления основной функции (уничтожение любых объектов с автоматическим временем хранения) и вызов std::exit с возвращаемым значением в качестве аргумента. Если элемент управления достигнет конца main без столкновения с оператором return, эффект заключается в выполнении

return 0;

В стандарте C ++ явно говорится: «Он [главная функция] должен иметь тип возвращаемого типа int , но в противном случае его тип определяется реализацией» и требует, чтобы в качестве параметров требовались те же две подписи, что и стандарт C. Таким образом, «void main ()» напрямую не допускается стандартом C ++, хотя он не может ничего сделать, чтобы остановить нестандартную реализацию, позволяющую альтернативы. Обратите внимание, что C ++ запрещает пользователю вызывать main (но стандарт C не имеет).

Существует параграф §18.5. Начало и завершение в стандарте C ++ 11, которое идентично абзацу из §7.22.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:

J.5.1 Аргументы среды

¶1 В размещенной среде основная функция получает третий аргумент char *envp[] , который указывает на массив указателей с нулевым символом на char , каждый из которых указывает на строку, которая предоставляет информацию об окружающей среде для этого выполнения программы (5.1.2.2.1).

Microsoft C

Интересен компилятор Microsoft VS 2010 . На веб-сайте говорится:

Синтаксис объявления для main

 int main();

или, необязательно,

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

В качестве альтернативы main и wmain функции могут быть объявлены как возвращающие void (без возвращаемого значения). Если вы объявляете main или wmain как возвращающий void, вы не можете вернуть код выхода в родительский процесс или операционную систему, используя оператор return. Чтобы вернуть код выхода, если main или wmain объявлен как void , вы должны использовать функцию 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 «Соответствие» относится к следующему:

¶5 Строго соответствующая программа должна использовать только те особенности языка и библиотеки, которые указаны в этом Международном стандарте. 3) Он не должен производить вывод, зависящий от любого неопределенного, неопределенного или определенного поведением поведения и не должен превышать минимальный предел реализации.

¶6 Две формы согласованной реализации организованы и автономны . Соответствующая хостинговая реализация должна принимать любую строго соответствующую программу. Соответствующая независимая реализация должна принимать любую строго соответствующую программу, в которой использование функций, указанных в разделе библиотеки (раздел 7), ограничивается содержимым стандартных заголовков <float.h> , <iso646.h> , <limits.h> , <stdalign.h> , <stdarg.h> , <stdbool.h> , <stddef.h> , <stdint.h> и <stdnoreturn.h> . Соответствующая реализация может иметь расширения (включая дополнительные функции библиотеки) при условии, что они не изменят поведение любой строго соответствующей программы. 4)

¶7 Соответствующая программа является приемлемой для соответствующей реализации. 5)

3) Строго соответствующая программа может использовать условные функции (см. 6.10.8.3), если использование защищено соответствующей условной инструкцией по предварительной обработке включения с использованием соответствующего макроса. Например:

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

4) Это означает, что соответствующая реализация не содержит идентификаторов, кроме тех, которые явно зарезервированы в настоящем Международном стандарте.

5) Строго совместимые программы должны быть максимально переносимыми между соответствующими реализациями. Соответствующие программы могут зависеть от непереносимых функций соответствующей реализации.

Примечательно, что единственным заголовком, требуемым для автономной среды, которая фактически определяет любые функции, является <stdarg.h> (и даже те, которые могут быть - и часто - просто макросами).

Стандартный C ++ - Свободная среда

Так же, как стандарт C распознает как размещенную, так и автономную среду, так же, как и стандарт C ++. (Цитаты из ИСО / МЭК 14882: 2011.)

1.4 Соответствие требованиям [intro.compliance]

¶7 Определены два вида реализации: размещенная реализация и самостоятельная реализация . Для размещенной реализации этот международный стандарт определяет набор доступных библиотек. Внештатной реализацией является реализация, которая может выполняться без использования операционной системы и имеет набор библиотек, поддерживающих реализацию, которые включают в себя определенные библиотеки поддержки языков (17.6.1.3).

¶8 Соответствующая реализация может иметь расширения (включая дополнительные функции библиотеки) при условии, что они не изменят поведение какой-либо хорошо сформированной программы. Реализации необходимы для диагностики программ, которые используют такие расширения, которые плохо сформированы в соответствии с этим Международным стандартом. Однако, сделав это, они могут компилировать и выполнять такие программы.

¶9 Каждая реализация должна включать документацию, которая идентифицирует все условно поддерживаемые конструкции, которые она не поддерживает, и определяет все специфические для локали характеристики. 3

3) В этой документации также определяется поведение, определяемое реализацией; см. 1.9.

17.6.1.3 Внештатные реализации [соблюдение]

Определены два вида реализации: хостинг и автономный (1.4). Для размещенной реализации этот международный стандарт описывает набор доступных заголовков.

У автономной реализации есть определенный набор заголовков, определенный реализацией. Этот набор должен включать по меньшей мере заголовки, показанные в таблице 16.

Приведенная версия заголовка <cstdlib> должна объявлять, по крайней мере, функции abort , atexit , at_quick_exit , exit и quick_exit (18.5). Другие заголовки, перечисленные в этой таблице, должны отвечать тем же требованиям, что и для размещенной реализации.

Таблица 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?

Стандарт §5.1.2.2.1 стандарта С11 показывает предпочтительную нотацию - int main(void) - но в стандарте также есть два примера, которые показывают int main() : §6.5.3.4 ¶8 и §6.7.6.3 ¶20 . Теперь важно отметить, что примеры не являются «нормативными»; они являются лишь иллюстративными. Если в примерах есть ошибки, они не влияют непосредственно на основной текст стандарта. Тем не менее, они сильно указывают на ожидаемое поведение, поэтому, если стандарт включает int main() в примере, это предполагает, что int main() не запрещен, даже если он не является предпочтительной нотацией.

6.5.3.4 Операторы sizeof и _Alignof

...

¶8 ПРИМЕР 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 ++ определяют два типа реализаций: автономные и размещенные.

  • Среда размещения C90

    Разрешенные формы 1 :

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */
    

    Комментарии:

    Первые два явно указаны как допустимые формы, другие неявно разрешены, потому что C90 допускает «неявный int» для возвращаемого типа и параметров функции. Никакой другой формы не допускается.

  • Свободная среда C90

    Разрешена любая форма или название основного объекта.

  • Среда размещения в среде C99

    Разрешенные формы 3 :

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    

    Комментарии:

    C99 удалил «implicit int», поэтому main() больше недействителен.

    Было введено странное, неоднозначное предложение «или каким-то другим способом, определенным реализацией». Это можно интерпретировать как «параметры для int main() могут отличаться» или «main может иметь любую форму, определенную для реализации».

    Некоторые компиляторы решили интерпретировать стандарт последним. Можно утверждать, что нелегко утверждать, что они не строго соответствуют, ссылаясь на стандарт сам по себе, так как он неоднозначен.

    Однако, чтобы разрешить полностью дикие формы main() вероятно, (?) Не было намерения этого нового предложения. Обоснование C99 (не нормативное) подразумевает, что предложение относится к дополнительным параметрам к int main 4 .

    Тем не менее, раздел для ратификации среды размещенной среды затем продолжает спорить о случае, когда main не возвращает int 5 . Хотя этот раздел не является нормативным для того, как следует объявлять основную информацию, это, безусловно, означает, что основная часть может быть объявлена ​​полностью определенным образом даже в размещенных системах.

  • Свободная среда C99

    Разрешена любая форма или название основного объекта.

  • Среда размещения C11

    Разрешенные формы 7 :

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    
  • C11 автономная среда

    Разрешена любая форма или название основного объекта.

Обратите внимание, что int main() никогда не указывалась как допустимая форма для любой размещенной реализации C в любой из вышеперечисленных версий. В C, в отличие от C ++, () и (void) имеют разные значения. Первый - устаревшая функция, которая может быть удалена с языка. См. Дальнейшие языковые направления C11:

6.11.6 Объявление функций

Использование деклараторов функций с пустыми круглыми скобками (не деклараторами типа параметров прототипа) является устаревшей функцией.

  • Среда размещения C ++ 03

    Разрешенные формы 9 :

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

    Комментарии:

    Обратите внимание на пустую скобку в первой форме. C ++ и C в этом случае разные, потому что в C ++ это означает, что функция не принимает никаких параметров. Но в C это означает, что он может принимать любой параметр.

  • Свободная среда C ++ 03

    Имя функции, вызываемой при запуске, определяется реализацией. Если он называется main() он должен следовать указанным формам 10 :

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • Среда размещения на C ++ 11

    Разрешенные формы 11 :

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

    Комментарии:

    Текст стандарта был изменен, но он имеет то же значение.

  • Свободная среда C ++ 11

    Имя функции, вызываемой при запуске, определяется реализацией. Если он называется main() он должен следовать указанным формам 12 :

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    

Рекомендации

  1. ANSI X3.159-1989 2.1.2.2 Хостинг среды. «Запуск программы»

    Функция, вызванная при запуске программы, называется main. Реализация не объявляет прототипа для этой функции. Он должен быть определен с типом возврата int и без параметров:

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

    или с двумя параметрами (называемыми здесь argc и argv, хотя любые имена могут использоваться, поскольку они являются локальными для функции, в которой они объявлены):

    int main(int argc, char *argv[]) { /* ... */ }
    
  2. ANSI X3.159-1989 2.1.2.1 Внештатная среда:

    В автономной среде (в которой выполнение программы C может иметь место без какой-либо выгоды от операционной системы), имя и тип функции, вызываемой при запуске программы, определяются в соответствии с реализацией.

  3. ISO 9899: 1999 5.1.2.2. Хостинговая среда -> 5.1.2.2.1. Запуск программы.

    Функция, вызванная при запуске программы, называется main. Реализация не объявляет прототипа для этой функции. Он должен быть определен с типом возврата int и без параметров:

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

    или с двумя параметрами (называемыми здесь argc и argv, хотя любые имена могут использоваться, поскольку они являются локальными для функции, в которой они объявлены):

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

    или эквивалент, 9) или каким-либо другим способом реализации.

  4. Обоснование международного стандарта - Языки программирования - C, редакция 5.10. 5.1.2.2 Хостинговая среда -> 5.1.2.2.1 Запуск программы

    Поведение аргументов main, а также взаимодействия выхода, main и atexit (см. §7.20.4.2) было кодифицировано для ограничения некоторого нежелательного многообразия в представлении строк argv и в значении значений, возвращаемых main.

    Спецификация argc и argv в качестве аргументов для основного признает обширную предыдущую практику. argv [argc] требуется, чтобы он был нулевым указателем, чтобы обеспечить избыточную проверку конца списка, также на основе обычной практики.

    main - единственная функция, которую можно условно объявить либо с нулевым, либо с двумя аргументами. (Количество аргументов других функций должно точно совпадать между вызовом и определением.) Этот специальный случай просто распознает распространенную практику отказа от аргументов main, когда программа не имеет доступа к строкам аргументов программы. Хотя многие реализации поддерживают более двух аргументов в основном, такая практика не поддерживается и не запрещена Стандартом; программа, определяющая main с тремя аргументами, строго не соответствует (см. §J.1.1.).

  5. ISO 9899: 1999 5.1.2.2 Хостинговая среда -> 5.1.2.2.3 Окончание программы

    Если тип возврата основной функции является типом, совместимым с int, возврат от начального вызова к основной функции эквивалентен вызову функции выхода со значением, возвращаемым основной функцией в качестве аргумента; 11) достижение того, }что завершается основная функция возвращает значение 0. Если тип возврата несовместим с int, статус завершения, возвращаемый в среду хоста, не указан.

  6. ISO 9899: 1999 5.1.2.1 Внештатная среда

    В автономной среде (в которой выполнение программы C может иметь место без какой-либо выгоды от операционной системы), имя и тип функции, вызываемой при запуске программы, определяются в соответствии с реализацией.

  7. ISO 9899: 2011 5.1.2.2. Хостинговая среда -> 5.1.2.2.1. Запуск программы.

    Этот раздел идентичен приведенному выше C99.

  8. ISO 9899: 1999 5.1.2.1 Внештатная среда

    Этот раздел идентичен приведенному выше C99.

  9. ISO 14882: 2003 3.6.1 Основная функция

    Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь тип возвращаемого типа int, но в противном случае его тип определяется реализацией. Все реализации должны учитывать оба следующих определения:

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

    а также

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882: 2003 3.6.1 Основная функция

    Реализация определяется, требуется ли программа в автономной среде для определения основной функции.

  11. ISO 14882: 2011 3.6.1 Основная функция

    Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь тип возвращаемого типа int, но в противном случае его тип определяется реализацией. Все реализации должны

    - функция (), возвращающая int и

    - функция (int, указатель на указатель на char), возвращающая int

    как тип основного (8.3.5).

  12. ISO 14882: 2011 3.6.1 Основная функция

    Этот раздел идентичен приведенному выше C ++ 03.




Имейте в виду, что даже если вы возвращаете int, некоторые ОС (Windows) обрезают возвращаемое значение на один байт (0-255).




Возвращаемое значение может использоваться операционной системой для проверки того, как программа была закрыта.

Возвращаемое значение 0 обычно означает «ОК» в большинстве операционных систем (те, о которых я могу думать в любом случае).

Он также может быть проверен, когда вы вызываете процесс самостоятельно, и посмотрите, была ли программа завершена и закончена правильно.

Это не просто соглашение о программировании.




У меня создалось впечатление, что стандарт указывает, что main не нуждается в возвращаемом значении, поскольку успешное возвращение было основано на ОС (ноль в одном может быть либо успешным, либо неудачным в другом), поэтому отсутствие возврата было репликой для компилятор, чтобы вставить успешное возвращение.

Однако я обычно возвращаю 0.




То, что нужно вернуть, зависит от того, что вы хотите сделать с исполняемым файлом. Например, если вы используете вашу программу с оболочкой командной строки, то вам нужно вернуть 0 для успеха и не равен нулю для отказа. Тогда вы сможете использовать программу в оболочках с условной обработкой в ​​зависимости от результата вашего кода. Также вы можете назначить любое ненулевое значение в соответствии с вашей интерпретацией, например, для критических ошибок разные точки выхода программы могут заканчивать программу с разными значениями выхода и которая доступна вызывающей оболочке, которая может решить, что делать, проверяя возвращаемое значение. Если код не предназначен для использования с оболочками, а возвращаемое значение никого не беспокоит, тогда оно может быть опущено. Я лично использую подписьint main (void) { .. return 0; .. }




Каков правильный (наиболее эффективный) способ определения функции main () в C и C ++ - int main () или void main () - и почему?

Эти слова «(наиболее эффективные)» не меняют вопроса. Если вы не находитесь в автономной среде, есть один универсально правильный способ объявить main(), и это как возвращение int.

Что должно main()возвращаться на C и C ++?

Это не то , что должен main() вернуться, это то , что делает main() вернуться. main()это, конечно же, функция, которую вызывает кто-то другой. Вы не имеете никакого контроля над кодом, который вызывает main(). Поэтому вы должны объявить main()с подписями типа, чтобы соответствовать его вызывающему. У вас просто нет выбора в этом вопросе. Вам не нужно спрашивать себя, что более или менее эффективно, или что лучше или хуже, или что-то в этом роде, потому что ответ уже отлично определен для вас по стандартам C и C +. Просто следуй за ними.

Если int main () возвращает 1 или возвращает 0?

0 для успеха, отличное от нуля для отказа. Опять же, не то, что вам нужно (или получить) выбрать: он определяется интерфейсом, который вы должны соблюдать.




Вот небольшая демонстрация использования кодов возврата ...

При использовании различных инструментов, которые предоставляет терминал Linux, можно использовать код возврата, например, для обработки ошибок после завершения процесса. Представьте, что присутствует следующий текстовый файл myfile:

Это пример, чтобы проверить работу grep.

Когда вы выполняете команду grep, создается процесс. Как только он пройдет (и не сломается), он возвращает код от 0 до 255. Например:

$ grep order myfile

Если вы это сделаете

$ echo $?
$ 0

вы получите 0. Почему? Поскольку grep нашел совпадение и вернул код выхода 0, что является обычным значением для выхода с успехом. Давайте проверим его снова, но с чем-то, что не находится внутри нашего текстового файла, и поэтому совпадения не будет найдено:

$ grep foo myfile
$ echo $?
$ 1

Поскольку grep не смог сопоставить токен «foo» с содержимым нашего файла, код возврата равен 1 (это обычный случай, когда происходит сбой, но, как указано выше, у вас есть множество значений на выбор).

Теперь следующий сценарий bash (просто введите его в терминале Linux), хотя очень базовый должен дать некоторое представление об обработке ошибок:

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

После второй строки ничего не печатается на терминале, так как «foo» сделал grep return 1, и мы проверяем, равен ли код возврата grep равным 0. Второй условный оператор перекликается с его сообщением в последней строке, поскольку он истинен из-за CHECK == 1.

Как вы можете видеть, если вы вызываете этот и этот процесс, иногда необходимо увидеть, что оно вернуло (по возвращаемому значению main ()).




Related

c++ c return-value main return-type