Я получаю этот код:
#include<stdio.h>
#include<stdlib.h>
void main(void)
{
char *ptr = (char*)malloc(10);
if(NULL == ptr)
{
printf("\n Malloc failed \n");
return;
}
else
{
// Do some processing
free(ptr);
}
return;
}
Он успешно компилируется в Visual C, но не компилируется в gcc, я получаю "error:" main "должен возвращать" int ". Таким образом, возвращаемый тип 'int' функции main() - это соглашение (которое для определения компилятора) или правило C?
Ответ 1
В стандарте C (ISO/IEC 9899: 2011) говорится:
5.1.2.2.1 Запуск программы
1 Функция, вызванная при запуске программы, называется main
. Реализация не объявляет прототип для этой функции. Он определяется с типом возврата int
и без Параметры:
int main(void) { /* ... */ }
или с двумя параметрами (называемыми здесь argc
и argv
, хотя любые имена могут быть используются, поскольку они являются локальными для функции, в которой они объявлены):
int main(int argc, char *argv[]) { /* ... */ }
или эквивалент; 10) или каким-либо другим способом реализации.
10) Таким образом, int
можно заменить на имя typedef, определенное как int
, или тип argv можно записать как char **argv
и т.д.
Таким образом, единственное переносимое объявление для main()
имеет тип возврата int
. Если MSVC определяет, что void
разрешен ('или каким-либо другим способом, определенным реализацией'), пусть будет так, но не ожидайте, что код будет переносимым. Старые версии компиляторов Microsoft (вплоть до MSVC 2005) не разрешают void main()
: см. Документацию на main
: запуск программы и main
Выполнение функций и программ. Однако MSVC 2008 и более поздние версии документированы, чтобы разрешить void main()
: см. main
: Запуск программы. Форма с тремя аргументами main()
отмечена как общее расширение в Приложении J:
J.5 Общие расширения
Следующие расширения широко используются во многих системах, но не переносимы для всех Реализации. Включение любого расширения, которое может привести к строгому соответствию программа становится недействительной, что делает несоответствие реализации. Примеры таких расширения - это новые ключевые слова, дополнительные функции библиотеки, объявленные в стандартных заголовках, или предопределенные макросы с именами, которые не начинаются с подчеркивания.
J.5.1 Аргументы среды
В размещенной среде функция main
получает третий аргумент, char *envp[]
,, который указывает на нуль-завершенный массив указателей на char
, каждый из которых указывает на строку который предоставляет информацию об окружающей среде для этого выполнения программы (5.1.2.2.1).
Значение, возвращаемое из 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 - возможно?.
7.22.4.4 Функция exit
¶5 Наконец, управление возвращается в среду хоста. Если значение status
равно нулю или EXIT_SUCCESS
, возвращается форма завершения успешного завершения статуса. Если значение status
равно EXIT_FAILURE
, возвращается форма выполнения неудачного завершения. В противном случае возвращаемый статус определяется реализацией.
Ответ 2
void main()
является нестандартным C и int main()
является стандартом.
Ответ 3
В соответствии с c стандартом main()
следует возвращать целое число для информирования об успехе или неудаче. Обычно для успеха он возвращает ноль, а для отказа возвращает целочисленное значение (положительное или отрицательное).
Обычно main объявляется как
int main(void);
поэтому он ожидает целое число как возвращаемый тип.
Если имеются аргументы командной строки,
int main(int argc,char *argv[]);