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

564
задан Joel 15 окт. '08 в 15:13
источник поделиться
20 ответов

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

int main()

и

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

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

int main(int argc, char** argv)

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

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

474
ответ дан workmad3 15 окт. '08 в 15:16
источник поделиться

Принятый ответ кажется нацеленным на С++, поэтому я решил добавить ответ, относящийся к C, и это несколько отличается.

ISO/IEC 9899: 1989 (C90):

main() должен быть объявлен как:

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

Или эквивалентно. Например, int main(int argc, char *argv[]) эквивалентен второму. Кроме того, возвращаемый тип int может быть опущен, поскольку он по умолчанию.

Если реализация позволяет это, main() может быть объявлен другими способами, но это делает реализацию программы определенной и более строго не соответствует.

Стандарт определяет 3 значения для возвращаемого значения, которые строго соответствуют (то есть не зависят от поведения, определенного реализацией): 0 и EXIT_SUCCESS для успешного завершения и EXIT_FAILURE для неудачного завершения. Любые другие значения являются нестандартными, а реализация определена. main() должен иметь явный оператор return в конце, чтобы избежать поведения undefined.

Наконец, нет ничего неправильного с точки зрения стандартов с вызовом main() из программы.

ISO/IEC 9899: 1999 (C99):

Для C99 все то же, что и выше, кроме:

  • Возвращаемый тип int не может быть опущен.
  • Вы можете опустить оператор return из main(). Если вы это сделаете, и main() закончен, есть неявный return 0.
138
ответ дан Chris 16 окт. '08 в 12:59
источник поделиться

Стандартная 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() возвращает, но не указывает возвращаемое значение; поэтому он приводит к поведению undefined.

7.22.4.4 Функция exit

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

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

В стандарте С++ 11 (ISO/IEC 14882: 2011) говорится:

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

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

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

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 рекомендуется добавлять дополнительные (необязательные) параметры. -конец примечание]

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

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

return 0;

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

В стандарте С++ 11 есть абзац §18.5 Начало и завершение, которое идентично абзацу из §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 и С++. Он только предписывает форму трех аргументов, где третий аргумент char **envp, указатель на список переменных среды.

На странице Microsoft также перечислены некоторые другие альтернативы - wmain(), которые принимают широкие строки символов и некоторые другие.

Microsoft Visual Studio 2005 версия эта страница не перечисляет void main() в качестве альтернативы. версии из Microsoft Visual Studio 2008 и далее.

Стандартная C - независимая среда

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

5.1.2 среды выполнения

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

5.1.2.1 Свободная среда

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

Эффект завершения программы в автономной среде определяется реализацией.

Перекрестная ссылка к разделу 4 Соответствие означает следующее:

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

¶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 распознает как размещенную, так и автономную среду, так же, как и стандарт С++. (Цитаты из ИСО/МЭК 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 - Заголовки С++ для автономных реализаций

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 стандарта C11 показывает предпочтительную нотацию - 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;
}
99
ответ дан Jonathan Leffler 10 сент. '13 в 17:15
источник поделиться

Я считаю, что main() должен возвращать либо EXIT_SUCCESS, либо EXIT_FAILURE. Они определены в stdlib.h

56
ответ дан dmityugov 15 окт. '08 в 15:33
источник поделиться

Возврат 0 при успехе и ненулевое значение для ошибки. Это стандарт, используемый сценариями UNIX и DOS, чтобы узнать, что произошло с вашей программой.

27
ответ дан Lou Franco 15 окт. '08 в 15:16
источник поделиться

Обратите внимание, что стандарты 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

    Разрешена любая форма или название main 2.

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

    Допустимые формы 3:

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

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

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

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

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

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

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

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

    Разрешена любая форма или название main 6.

  • среда с включенным C11

    Допустимые формы 7:

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

    Разрешена любая форма или название main 8.


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

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

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


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

    Допустимые формы 9:

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

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

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

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

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

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

    Допустимые формы 11:

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

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

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

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

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

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

Ссылки

  • ANSI X3.159-1989 2.1.2.2 Хостинговая среда. "Запуск программы"

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

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

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

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

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

  • 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) или в некоторых других реализациях образом.

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

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

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

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

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

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

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

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

  • ISO 9899: 2011 5.1.2.2 Хостинг-среда → 5.1.2.2.1 Запуск программы

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

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

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

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

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

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

    и

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

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

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

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

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

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

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

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

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

26
ответ дан Lundin 07 июля '15 в 11:07
источник поделиться

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

7
ответ дан Ferruccio 15 окт. '08 в 18:22
источник поделиться

main() в C89 и K & R C неопределенные типы возврата по умолчанию для int.

return 1? return 0?
  • Если вы не пишете оператор return в int main(), закрывающий { по умолчанию возвращает 0.

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

Смотрите Как я могу получить возвращаемую мою главную функцию?.

$ ./a.out
$ echo $?

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

В сценариях Unix и DOS обычно возвращаются return 0 на успех и ненулевое значение для ошибки. Это стандарт, используемый сценариями Unix и DOS, чтобы узнать, что произошло с вашей программой и контролировать весь поток.

6
ответ дан Jeegar Patel 27 дек. '12 в 11:02
источник поделиться

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

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

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

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

4
ответ дан Yochai Timmer 01 июля '11 в 19:32
источник поделиться

Возвращаемое значение main() показывает, как вышла программа. Если возвращаемое значение равно zero, это означает, что выполнение было успешным, в то время как любое ненулевое значение будет представлять, что что-то ухудшилось при выполнении.

3
ответ дан Fahad Uddin 02 июля '11 в 2:30
источник поделиться

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

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

2
ответ дан graham.reeds 15 окт. '08 в 15:42
источник поделиться

Возврат 0 должен сообщить программисту, что программа успешно завершила задание.

2
ответ дан Vamsi Pavan Mahesh 23 нояб. '12 в 10:29
источник поделиться

В С++ основная функция должна быть объявлена ​​как int main(), а не void main(), поскольку компилятор затем выдает ошибку в случае void main. Основная функция может принимать любое количество аргументов, таких как int main (int k, int l, int arr []) или 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

Прибывая в возвращаемую часть, он должен вернуть только 0, иначе компилятор выдает ошибку. например, если вы вернете 1, вы получите желаемый результат, но он также выдает ошибку времени выполнения.

Пример

#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
1
ответ дан Somit 23 февр. '18 в 8:26
источник поделиться

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

1
ответ дан phoxis 10 марта '11 в 17:11
источник поделиться

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

Если вы это делаете (вызывается процесс столько раз), вы должны найти способ разместить свою логику непосредственно внутри вызывающего или в DLL файле, не выделяя определенный процесс для каждого вызова; множественные распределения процессов приносят вам соответствующую проблему с эффективностью в этом случае.

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

1
ответ дан Luca C. 03 марта '11 в 14:56
источник поделиться

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

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

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

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

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

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

0
ответ дан Steve Summit 04 окт. '17 в 0:56
источник поделиться

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

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

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

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

$ grep order myfile

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

$ echo $?
$ 0

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

$ grep foo myfile
$ echo $?
$ 1

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

Теперь следующий bash script (просто введите его в терминале 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()).

0
ответ дан rbaleksandar 11 февр. '15 в 1:22
источник поделиться

Опустить return 0

Когда программа C или С++ достигает конца main, компилятор автоматически сгенерирует код для возврата 0, поэтому нет необходимости помещать return 0; явно в конце main.

Примечание:, когда я делаю это предложение, он почти всегда сопровождается одним из двух видов комментариев: "Я этого не знал". или "Это плохой совет!" Мое обоснование заключается в том, что безопасно и полезно полагаться на поведение компилятора, явно поддерживаемое стандартом. Для C, поскольку C99; см. раздел 5.1.2.2.3 стандарта ISO/IEC 9899: 1999:

[...] возврат от начального вызова к функции main эквивалентен вызову функции exit со значением, возвращаемым функцией main в качестве аргумента; достижение }, которое завершает функцию main, возвращает значение 0.

Для С++, начиная с первого стандарта в 1998 году; см. раздел ИСО/МЭК 14882: 1998 раздел 3.6.1:

Если элемент управления достигнет конца main без столкновения с оператором return, эффект будет выполняться при возврате 0;

Все версии обоих стандартов с тех пор (C99 и С++ 98) поддерживают ту же идею. Мы полагаемся на автоматически сгенерированные функции-члены в С++, и немногие люди пишут явные инструкции return; в конце функции void. Причины против пропусков, похоже, сводятся к "это выглядит странно" . Если, как и я, вам будет интересно узнать о причине изменения стандарта C прочитать этот вопрос. Также обратите внимание, что в начале 1990-х годов это считалось "неряшливой практикой", поскольку в то время это было undefined (хотя и широко поддерживается).

Поэтому я защищаю его; другие не согласны (часто яростно!) В любом случае, если вы столкнетесь с кодом, который его не выпускает, вы будете знать, что он явно поддерживается стандартом, и вы узнаете, что это значит.

0
ответ дан Edward 22 апр. '17 в 14:34
источник поделиться

В основном это зависит от среды выполнения (ОС). C подразумевает, что он будет запускаться под UNIX-подобной ОС, которая ожидает, что программа вернет целое число (небольшое? 1 байт? Не может запомнить), чтобы указать успех/сбой.

Вероятно, вы должны просто использовать int main(int argc, char** argv).

-1
ответ дан Daren Thomas 15 окт. '08 в 15:18
источник поделиться

void main() запрещено после C90. main должно возвращать значение. Я использовал для возврата 0.

-1
ответ дан Ezio 20 июня '13 в 4:09
источник поделиться

Другие вопросы по меткам