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



Answers

Принятый ответ, похоже, предназначен для C ++, поэтому я подумал, что добавлю ответ, относящийся к 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 в конце, чтобы избежать неопределенного поведения.

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

ISO / IEC 9899: 1999 (C99):

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

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



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




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

    The behavior of the arguments to main, and of the interaction of exit, main and atexit (see §7.20.4.2) has been codified to curb some unwanted variety in the representation of argv strings, and in the meaning of values returned by main.

    The specification of argc and argv as arguments to main recognizes extensive prior practice. argv[argc] is required to be a null pointer to provide a redundant check for the end of the list, also on the basis of common practice.

    main is the only function that may portably be declared either with zero or two arguments. (The number of other functions' arguments must match exactly between invocation and definition.) This special case simply recognizes the widespread practice of leaving off the arguments to main when the program does not access the program argument strings. While many implementations support more than two arguments to main, such practice is neither blessed nor forbidden by the Standard; a program that defines main with three arguments is not strictly conforming (see §J.5.1.).

  5. ISO 9899:1999 5.1.2.2 Hosted environment --> 5.1.2.2.3 Program termination

    If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

  6. ISO 9899:1999 5.1.2.1 Freestanding environment

    In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.

  7. ISO 9899:2011 5.1.2.2 Hosted environment -> 5.1.2.2.1 Program startup

    This section is identical to the C99 one cited above.

  8. ISO 9899:1999 5.1.2.1 Freestanding environment

    This section is identical to the C99 one cited above.

  9. ISO 14882:2003 3.6.1 Main function

    An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:

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

    and

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882:2003 3.6.1 Main function

    It is implementation-defined whether a program in a freestanding environment is required to define a main function.

  11. ISO 14882:2011 3.6.1 Main function

    An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both

    — a function of () returning int and

    — a function of (int, pointer to pointer to char) returning int

    as the type of main (8.3.5).

  12. ISO 14882:2011 3.6.1 Main function

    This section is identical to the C++03 one cited above.




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

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

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

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

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

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




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

However I usually return 0.




Here is a small demonstration of the usage of return codes...

When using the various tools that the Linux terminal provides one can use the return code for example for error handling after the process has been completed. Imagine that the following text file myfile is present:

This is some example in order to check how grep works.

When you execute the grep command a process is created. Once it is through (and didn't break) it returns some code between 0 and 255. For example:

$ grep order myfile

If you do

$ echo $?
$ 0

you will get a 0. Why? Because grep found a match and returned an exit code 0, which is the usual value for exiting with a success. Let's check it out again but with something that is not inside our text file and thus no match will be found:

$ grep foo myfile
$ echo $?
$ 1

Since grep failed to match the token "foo" with the content of our file the return code is 1 (this is the usual case when a failure occurs but as stated above you have plenty of values to choose from).

Now the following bash script (simply type it in a Linux terminal) although very basic should give some idea of error handling:

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

After the second line nothing is printed to the terminal since "foo" made grep return 1 and we check if the return code of grep was equal to 0. The second conditional statement echoes its message in the last line since it is true due to CHECK == 1.

As you can see if you are calling this and that process it is sometimes essential to see what it has returned (by the return value of main()).




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

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

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




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

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

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

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

$ ./a.out
$ echo $?

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

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




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




Related