Стандарт 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]
включно повинні містити покажчики на рядки, яким задається реалізація значеннями хост-середовищем перед запуском програми. Наміром є подання програмної інформації, визначеної до запуску програми, з інших місць в розміщеному середовищі. Якщо хост-середовище не здатне подавати рядки з літерами як у великому, так і в малому регістрі, реалізація повинна забезпечити отримання рядків рядками.
- Якщо значення
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
Функція
Finally5 Нарешті, контроль повертається у головне середовище. Якщо значення status
дорівнює нулю, або повертається EXIT_SUCCESS
визначена реалізацією форма успішного завершення стану . Якщо значення status
є EXIT_FAILURE
, повертається визначена реалізацією форма невдалого припинення статусу . Інакше повернутий статус визначається реалізацією.
Стандартний C ++ - розміщене середовище
Стандарт C ++ 11 (ISO / IEC 14882: 2011) говорить:
3.6.1 Основна функція [basic.start.main]
¶1 Програма повинна містити глобальну функцію, яку називають основною, яка позначається початком програми. [...]
¶2 Реалізація не повинна визначати головну функцію. Ця функція не повинна перевантажуватися. Він повинен мати тип повернення типу int, але в іншому випадку визначено його тип реалізації. Усі реалізації повинні дозволяти обидва наступні визначення основних:
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
. —Закінчити примітку]
¶3 Функція main
не повинна використовуватися в межах програми. Зв'язок (3.5) з програми main
визначається реалізацією. [...]
¶5 Оператор повернення в основному має наслідком залишення основної функції (знищення будь-яких об'єктів з автоматичною тривалістю зберігання) та виклик std::exit
із значенням повернення як аргумент. Якщо контроль доходить до кінця основного, не стикаючись з оператором return, ефект буде виконати
return 0;
Стандарт C ++ прямо говорить: "Він [основна функція] повинен мати тип повернення типу int
, але в іншому випадку його тип визначений реалізацією", і вимагає тих же двох підписів, що і стандарт C, щоб підтримуватися як параметри. Таким чином, стандарт C ++ прямо не заборонено "void main ()", хоча він нічого не може зробити, щоб зупинити нестандартну реалізацію, що дозволяє альтернативи. Зауважте, що C ++ забороняє користувачеві телефонувати main
(але стандарт C це не робить).
Там в пункті §18.5 Початок і закінчення в C ++ 11 стандарт , який ідентичний пункту з §7.22.4.4 функції в стандарті C11 (процитованому вище), за винятком виноски (який просто документи, і визначаються в ).exit
EXIT_SUCCESS
EXIT_FAILURE
<cstdlib>
Стандарт С - загальне розширення
Класично системи Unix підтримують третій варіант:
int main(int argc, char **argv, char **envp) { ... }
Третій аргумент - це недійсний список покажчиків на рядки, кожен з яких є змінною середовища, яка має ім'я, знак рівності та значення (можливо, порожнє). Якщо ви цим не користуєтеся, ви все одно можете потрапити в оточення через " extern char **environ;
". Ця глобальна змінна є унікальною серед POSIX тим, що вона не має заголовка, який оголошує її.
Це визнано стандартом C як загальне розширення, задокументоване у Додатку J:
J.5.1 Аргументи навколишнього середовища
¶1 У розміщеному середовищі головна функція отримує третій аргумент, char *envp[]
який вказує на нульовий масив покажчиків на char
, кожен з яких вказує на рядок, що забезпечує інформацію про середовище для цього виконання програми (5.1. 2.2.1).
Microsoft C
Microsoft VS 2010 компілятор цікаво. Веб-сайт говорить:
Синтаксис оголошення для основного є
int main();
або, необов'язково,
int main(int argc, char *argv[], char *envp[]);
Як варіант, main
і wmain
функції можуть бути оголошені як повернені void
(значення повернення немає). Якщо ви оголошуєте main
або wmain
повертаєтесь як недійсним, ви не можете повернути вихідний код у батьківський процес або операційну систему, використовуючи оператор return. Щоб повернути код завершення , коли main
або wmain
оголошено void
, ви повинні використовувати exit
функцію.
Мені незрозуміло, що відбувається (який вихідний код повертається до батьківської або ОС), коли програма з програмою void main()
не працює - і веб-сайт MS теж мовчить.
Цікаво, що MS не призначає двоаргументуючої версії, якої main()
вимагають стандарти C та C ++. Він призначає лише три форми аргументів, де є третій аргумент char **envp
, вказівник на список змінних середовища.
Сторінка Microsoft також перелічує деякі інші альтернативи - для wmain()
яких потрібні широкі рядки символів та деякі інші.
Microsoft Visual Studio 2005 версія цієї сторінки НЕ список в void main()
якості альтернативи. У версії від Microsoft Visual Studio 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]
Are7 Визначено два види реалізації: розміщена реалізація та незалежна реалізація . Для розміщеної реалізації цей Міжнародний стандарт визначає набір доступних бібліотек. Автономна реалізація - це те, в якому виконання може відбуватися без переваги операційної системи та має визначений реалізацією набір бібліотек, який включає певні бібліотеки, що підтримують мову (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()
C?
Стандарт §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
оператори
…
EX8 ПРИКЛАД 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;
}