Тип возвращаемого значения функции 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?

3 ответа

Решение

Стандарт 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 функция

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

void main() является нестандартным C и int main() это стандарт.

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

 int main(void); 

поэтому он ожидает целое число в качестве возвращаемого типа.

Если есть аргументы командной строки,

int main(int argc,char *argv[]);
Другие вопросы по тегам