Возвращаемый тип функции main()

Я получаю этот код:

#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[]);