Это было полезно?

Решение

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

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++, поэтому я решил добавить ответ, относящийся к C, и он несколько отличается.

ИСО/МЭК 9899:1989 (C90):

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

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

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

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

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

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

ИСО/МЭК 9899:1999 (C99):

Для C99 все то же самое, что и выше, за исключением:

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

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

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

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

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

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

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

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 с возвращаемым значением в качестве аргумента.Если управление достигает конец основного, не сталкиваясь с оператором возврата, эффект от выполнения

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;'.Долгое время у этого не было заголовка, который бы это объявлял, но ПОСИКС Стандарт 2008 года теперь требует, чтобы он был объявлен в <unistd.h>.

Это признано стандартом C как общее расширение, документированное в Приложении J:

J.5.1 Аргументы окружающей среды

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

Майкрософт С

А Майкрософт против 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 Визуальная студия 2005 г. версия эта страница не перечисляет void main() как альтернатива.А версии от Майкрософт Визуальная студия 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++.(Цитаты из ISO/IEC 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() в С?

В стандарте §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;
}

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

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

    Допускается любая форма или имя 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() вероятно (?) не было целью этого нового предложения.Обоснование C99 (не нормативное) подразумевает, что предложение относится к дополнительным параметрам, int main 4.

    Тем не менее, в разделе о завершении программы размещенной среды продолжается обсуждение случая, когда main не возвращает int. 5.Хотя этот раздел не является нормативным относительно того, как следует объявлять main, он определенно подразумевает, что 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, в отличие от 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 Запуск программы

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

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

    main — единственная функция, которую можно объявить переносимо как с нулем, так и с двумя аргументами.(Количество аргументов других функций должно соответствовать точно между вызовами и определением.) Этот специальный случай просто признает широкую практику отказа от аргументов в основном, когда программа не получает доступа к строкам аргументов программы.Хотя многие реализации поддерживают более двух аргументов main, такая практика не одобрена и не запрещена Стандартом;программа, определяющая main с тремя аргументами, не является строго соответствующей (см. §J.5.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, но в остальном его тип определяется реализацией.Все реализации должны допускать оба следующих определения main:

    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.

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

main() в C89 и K&R C неуказанные типы возвращаемых значений по умолчанию равны «int».

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

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

Видеть Как я могу получить то, что вернула моя основная функция?.

$ ./a.out
$ echo $?

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

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

Имейте в виду, что даже если вы возвращаете целое число, некоторые операционные системы (Windows) усекают возвращаемое значение до одного байта (0–255).

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

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

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

Его НЕТ просто соглашение по программированию.

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

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

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

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

Пропускать return 0

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

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

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

Для C++ — с момента появления первого стандарта в 1998 году;см. ISO/IEC 14882:1998, раздел 3.6.1:

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

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

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

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

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

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

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

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

Каков правильный (наиболее эффективный) способ определения функции 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 вернуть 1, и мы проверяем, равен ли код возврата grep 0.Второй условный оператор повторяет свое сообщение в последней строке, поскольку оно истинно из-за CHECK == 1.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top