Почему main() в C++ нельзя встроить?

Я читал часто задаваемые вопросы по C++ и заметил одно предложение.

main() не может быть встроенным.

Почему это?


person jon    schedule 08.08.2011    source источник
comment
Более интересный вопрос для меня: почему кто-то хочет попытаться встроить его?   -  person RiaD    schedule 08.08.2011
comment
Чтобы встроить ваш основной код ядра ОС? :)   -  person Mehran    schedule 08.08.2011
comment
Это глупо, да? Встраивание — это когда содержимое метода помещается непосредственно в вызывающий код, а не как отдельный метод. Это означает, что вам нужно будет перекомпилировать вашу ОС, чтобы ваша функция main была скомпилирована в нее. Итак, ответ в том, что вы не можете перекомпилировать свою ОС?   -  person Kieren Johnstone    schedule 08.08.2011
comment
@Kieren: Вот почему вы никогда не хотите физически встраивать функцию. Строго говоря, это не то же самое, что функция не должна быть помечена inline (что, помните, всего лишь намек!).   -  person Lightness Races in Orbit    schedule 08.08.2011
comment
Включение этого в FAQ по C++ кажется мне глупым, потому что зачем вам это делать. Это похоже на то, когда вы видите предупреждение о ситуации, которая не имеет никакого смысла.   -  person jhocking    schedule 08.08.2011
comment
Это могло бы быть в FAQ просто для того, чтобы заставить людей задуматься о том, что такое встраивание, чтобы избежать людей, пытающихся оптимизировать код, встраивая main и тому подобное. Лично я считаю, что было бы лучше обязательно указать, что это просто намеки для компилятора.   -  person Hobblin    schedule 08.08.2011
comment
Я не согласен с близкими избирателями, но почему у этого вопроса ~ 40 голосов?   -  person Chris Lutz    schedule 10.08.2011
comment
хороший вопрос, его не следует закрывать   -  person Tebe    schedule 10.08.2011
comment
это пища для размышлений, что люди здесь считают дебаты неконструктивными. это правда, что SO активно препятствует дебатам. и мне кажется, что это привлекает людей, которые не понимают ценности дебатов. этот вопрос является очень ярким примером того, что отсутствие надлежащих условий для дебатов порождает неправильные представления. т. е. технически неверный ответ, выбранный в качестве решения, с 80+ голосами.   -  person Cheers and hth. - Alf    schedule 10.08.2011
comment
Связано: Ограничения на функцию main()   -  person Armen Tsirunyan    schedule 13.08.2011


Ответы (17)


В С++ недопустимо вызывать основную функцию в вашем коде, поэтому ее нельзя было бы встроить.

person sepp2k    schedule 08.08.2011
comment
Это есть причина, подумайте об этом. - person Tamás Szelei; 08.08.2011
comment
@iammilind: *static_cast<int*>(0) = 10 тоже компилируется, и это не значит, что это правильно... как в случае с любым нарушением ODR и многими другими вещами... тот факт, что она компилируется, не означает, что это легальная программа . - person David Rodríguez - dribeas; 08.08.2011
comment
@iammilind: заявление, которое он компилирует, требует контекста. Потому что стандарт не требует компиляции, и на самом деле компилируется не во всех случаях. - person Benjamin Lindley; 08.08.2011
comment
вздох для всех, кто интересуется, оп спросил в комментарии о причине, тогда я прокомментировал, отвечая ему, но он удалил свой. Не круто, оп. - person Tamás Szelei; 08.08.2011
comment
@iammilind: Просто для справки: код не компилируется на g++ с -pedantic-errors. - person sepp2k; 08.08.2011
comment
@iammilind: stackoverflow.com/questions/5177167/ - person Prasoon Saurav; 08.08.2011
comment
-1 Невозможно, чтобы это когда-либо было встроено, неверно. Кроме того, это лишь малая часть причины, совершенно не относящаяся к делу часть. :-) - person Cheers and hth. - Alf; 08.08.2011
comment
@Alf: Как это неправильно? Если мне не разрешено вызывать функцию, то где она может быть встроена? - person sepp2k; 08.08.2011
comment
@sepp2k: см. мой ответ. но вкратце, встраивание машинного кода не имеет отношения к вопросу, но технически его можно встроить в вызов из библиотеки времени выполнения двумя разными способами. однако это не делается, так как нет никакого преимущества. :-) - person Cheers and hth. - Alf; 08.08.2011
comment
@ sepp2k: физически встроенный код функции отличается от функции, помеченной inline. - person Lightness Races in Orbit; 08.08.2011
comment
@ Альф П. Штайнбах, на самом деле его нельзя встроить в библиотеку времени выполнения, потому что библиотека времени выполнения скомпилирована отдельно от вашего приложения и не # включает ваш заголовок во встроенное определение. - person psusi; 08.08.2011
comment
@psusi: вы ошибаетесь, и это уже обсуждалось. пожалуйста, прочитайте, прежде чем утверждать. - person Cheers and hth. - Alf; 08.08.2011
comment
@psusi: компоновщик может выполнять встраивание в определенных ситуациях. - person Lightness Races in Orbit; 08.08.2011
comment
@ Томалак Герет'кал, а? Компоновщик не генерирует asm. Вот почему вы должны поместить определение встроенного в заголовок; поэтому компилятор может увидеть определение и сгенерировать встроенный ассемблер. - person psusi; 08.08.2011
comment
@iammilind: Если вы вызываете main() из main(), то этот вызов определенно не может быть встроен ... (по крайней мере, не рекурсивно) - person Chris Lercher; 10.08.2011

Потому что стандарт говорит так:

[2003: 3.6.1/3]: Функция main не должна использоваться (3.2) в программе. Связь (3.5) main определяется реализацией. Программа, объявляющая main встроенной или статической, имеет неправильный формат. Имя main не зарезервировано для других целей. [Пример: функции-члены, классы и перечисления могут называться основными, как и сущности в других пространствах имен. ]

И почему так сказано? Потому что он пытается оставить как можно больше информации о реализации main на усмотрение индивидуума... ну, реализации... насколько это возможно, и не хочет ограничивать реализации, требуя, чтобы inline было действительным здесь, когда это необходимо. вряд ли имеет практическую пользу.


Мой друг в комитете подтвердил это:

Нет никаких причин, по которым inline main() не работали бы сами по себе. [..] У меня мог бы быть интерпретатор C++, который мог бы вызывать встроенный main(). [..] [Но] inline/static main() запрещены, чтобы избежать путаницы. Мне трудно представить, что обоснование может быть чем-то дополнительным к тому, что уже было сказано в [этих вопросах и ответах].


Кстати, не путайте ключевое слово подсказки inline с фактически встроенными функциями. Вы можете пометить функцию inline, и она может быть физически не встроена.

Таким образом, даже если верно, что main "нельзя встроить" (строго говоря, это неправда, хотя встраивание main было бы довольно неудобным и бессмысленным, как объясняется в других ответах), теоретически это все равно могло бы отлично поддерживает ключевое слово подсказки inline.

Это не по причине, указанной выше, и в ответе litb: это усложнит ситуацию без реальной пользы.

person Lightness Races in Orbit    schedule 08.08.2011
comment
+1 за цитирование стандарта. Однако это может не полностью ответить на вопрос ОП; пока что я не видел ни одного обоснованного ответа против, кроме вашего поста. - person Thomas Matthews; 08.08.2011
comment
@Thomas: Обоснование, которое я дал, почти такое же, как и в других ответах, только с меньшими подробностями относительно того, почему может не быть практической пользы. :) - person Lightness Races in Orbit; 08.08.2011
comment
re не хочет ограничивать реализации, требуя, чтобы встроенная строка была действительной, поддержка inline для main тривиальна, поскольку ее можно просто игнорировать, следовательно, это не ограничивает какую-либо реализацию, следовательно, эта возможная причина запрета стандарта не выдерживает критики. Извините. но я не могу предложить больше, чем в моем ответе, что нет смысла иметь inline (и в этом мы согласны, я думаю). - person Cheers and hth. - Alf; 09.01.2014
comment
@Cheersandhth.-Alf: Это как бы означает, что вы можете определить main в нескольких TU, если все определения лексически идентичны (среди других ограничений), что просто не имеет смысла, чтобы его стоило запрещать. - person Lightness Races in Orbit; 09.01.2014
comment
@LightnessRacesinOrbit: я понимаю, что вы имеете в виду, но... main быть функцией означает, что ее можно вызывать из пользовательского кода (за исключением того, что это не разрешено), что ее адрес можно взять (за исключением того, что это не разрешено), что это UB для потока вне конца (за исключением того, что это специально поддерживается и четко определено), что любой вызов должен соответствовать списку формальных аргументов (за исключением того, что на практике один и тот же вызов библиотеки времени выполнения вызывает его независимо от списка формальных аргументов) и так далее. То есть, поскольку main является очень особенным, обычные последствия легко определяются. Хотя это была хорошая идея. :) Но не получилось. :( - person Cheers and hth. - Alf; 09.01.2014
comment
Наоборот, вы только что опровергли свою собственную точку зрения, показав, как много специальных правил существует для main, которые на самом деле необходимы в существовании. - person Lightness Races in Orbit; 09.01.2014
comment
@LightnessRacesinOrbit: Что означает, что привязка main определяется реализацией? Почему это определяется реализацией? - person Destructor; 07.06.2015
comment
@meet: А почему бы и нет? В отличие от других функций, определяемых пользователем, main имеет значение, которое должно взаимодействовать со средой выполнения реализации и с основной операционной системой (поскольку это точка входа в программу), поэтому комитету людей нет смысла слишком много назначать по этому поводу. Напомним, что связывание других функций определяется пользователем, поэтому стандарт является немного ограничивающим main здесь, говоря: слушайте своего поставщика компилятора, потому что они могут выбирать этот не ты. :) - person Lightness Races in Orbit; 07.06.2015

Библиотека времени выполнения C должна найти этот символ, чтобы «знать», какую функцию запускать.

person Ringding    schedule 08.08.2011
comment
Означает ли это, что компоновщики не могут найти символы для других встроенных функций? - person Thomas Matthews; 08.08.2011
comment
@Thomas Matthews: зависит от того, насколько умен компоновщик. Вообще говоря, нет, компоновщики не знают о встроенных функциях; они имеют внутреннюю связь. Более современные компоновщики немного умнее в том смысле, что они пытаются оптимизировать всю программу, а это совершенно другая игра. :) - person Billy ONeal; 08.08.2011
comment
Я бы также сказал, что в среде выполнения C есть (обычно) явная функция call для функции main(), и она почти всегда связана динамически. Так что это просто не может работать в типичном случае. - person whitequark; 08.08.2011

Вы не можете напрямую вызвать main() (это запрещено в C++), поэтому нет смысла встраивать его.

person Karoly Horvath    schedule 08.08.2011
comment
Нет смысла и недостаточной причины полностью запрещать что-либо. Это [немного] больше, чем это. - person Lightness Races in Orbit; 11.08.2011

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

Теперь, если мы сможем inline использовать функцию main() и включить ее в заголовочный файл, тогда для каждой единицы перевода будет свое определение main(). Что не разрешено. Вы можете объявить main() в namespace и inline в нем. Но не глобальный main().

person iammilind    schedule 08.08.2011
comment
Вы можете сделать это и без inline. - person Lightness Races in Orbit; 08.08.2011
comment
@Tomalak, тогда это приведет к множественной ошибке определения. не так ли? - person iammilind; 08.08.2011
comment
Нет, если каждое определение имеет внутреннюю связь. (Обратите внимание, именно поэтому static int main() тоже имеет неправильный формат :D) - person Lightness Races in Orbit; 08.08.2011
comment
@ Томлак, да. static int main() эквивалентно namespace { int main() }. О чем я рассказал в ответе. - person iammilind; 08.08.2011
comment
Можно также встроить функцию и иметь только один ее экземпляр. Компиляторы и компоновщики могут идентифицировать несколько экземпляров функции main, так что вы хотите сказать? - person Thomas Matthews; 08.08.2011
comment
@ Томас, это нарушит ODR; если у кого-то есть несколько экземпляров. Какой экземпляр main() выбрать? - person iammilind; 08.08.2011
comment
Возьмем случай присвоения указателя функции встроенной функции. На какой экземпляр указывает указатель? Должен быть один экземпляр, удовлетворяющий этому условию. Точно так же ограничение на наличие только одного экземпляра main останется в силе. Хотя встроенная версия main может быть избыточной или бесполезной, я не вижу причин не разрешать ее. - person Thomas Matthews; 08.08.2011
comment
@iammilind: это не эквивалентно. Один запрещен; другой нет. - person Lightness Races in Orbit; 08.08.2011

во-первых, вы должны понять, как работает функция со встроенным

пример:

 inline void f() {
     int a  = 3;
     a += 3;
     cout << a;
 }

 int main() {
      f();
      return 0;
 }

будет выглядеть для компилятора как:

 int main() {
        int a  = 3;
        a += 3;
        cout << a;
        return 0;
 }

Глядя на этот пример, как вы хотите сделать main встроенным? Этот метод встроен сразу.

person nirmus    schedule 08.08.2011
comment
@the_drow: Я надеялся, что Нирмус увидит это и сам подумает об исправлении! Спасибо хоть! - person Lightness Races in Orbit; 08.08.2011
comment
Так в чем же разница между обработкой функции inlined, которая имеет только один вызов, и функции main, которая имеет только один вызов? - person Thomas Matthews; 08.08.2011
comment
This method is inline immediately. Неправда. inline — это всего лишь подсказка. Он не выполняет встраивание функций. - person Lightness Races in Orbit; 17.11.2012

В стандарте С++ говорится, что функция main не может быть встроена, согласно ответу @Tomalak Geret'kal. В этом ответе обсуждается возможность встраивания функции main, если ограничение в стандарте снято.

Определение Inline
Ключевое слово inline — это предложение компилятору вставить содержимое функции на место. Одно из намерений состоит в том, чтобы удалить накладные расходы, присутствующие при вызове и возврате из функции (подпрограммы).

Важной ситуацией встраивания является случай, когда есть указатель на функцию. В этом случае должна быть хотя бы одна статическая копия функции. В этом случае компоновщик может разрешить «внешние связи» встроенной функции, потому что существует одна статическая версия.

Важно отметить, что компилятор и компоновщик определяют, следует ли вставлять содержимое или вызывать один экземпляр функции.

Также следует отметить, что функции, которые не помечены программистом, также могут быть встроены компилятором.

Встраивание основной функции
Поскольку разрешен только один вызов main, как она связана, зависит от компилятора. Отдельные экземпляры встроенных функций разрешены Стандартом. Компилятору разрешено преобразовывать функцию inlined в вызов функции для одного экземпляра. Таким образом, компилятор проигнорировал бы встроенное предложение для функции main.

Компилятор и компоновщик должны убедиться, что существует только один экземпляр встроенной функции main. Здесь начинается сложная часть, особенно с внешней связью. Один из процессов обеспечения одного экземпляра состоит в том, чтобы оставить информацию о том, что перевод имеет «основную» функцию независимо от того, встроен он или нет. Примечание. Когда выполняется вызов встроенной функции, компилятору разрешается удалить функцию из таблиц символов для внешней компоновки, поскольку идея состоит в том, что функция не будет вызываться внешними функциями.

Резюме
Технически ничто не препятствует встраиванию функции main. Уже существует механизм для преобразования встроенных функций в отдельные экземпляры и для идентификации нескольких экземпляров функции. Когда есть указатель на встроенную функцию, создается единственный экземпляр функции, поэтому у него есть адрес. Этот механизм удовлетворит требованиям библиотеки времени выполнения для main, имеющего адрес. В случае inline для функции main она будет проигнорирована, но не должно быть никаких причин для предотвращения этого синтаксиса (кроме путаницы). Ведь уже есть синтаксические случаи, которые избыточны, например объявление параметра, который передается по значению (копии) как const.

- Это только мое мнение, я могу ошибаться. -- Деннис Миллер, комик.

person Thomas Matthews    schedule 08.08.2011

Другие отмечают, что вызов main не может быть осмысленно встроен на уровне машинного кода. Это мусор. Это потребует небольшой помощи от компоновщика (например, глобальной оптимизации) или перекомпиляции части библиотеки времени выполнения для каждого приложения, но это вполне выполнимо, здесь нет технических проблем.

Однако эффект подсказки inline, заключающийся в том, что вызовы предпочтительно должны быть встроенными, не имеет значения для функции, которая вызывается только один раз и на верхнем уровне управления, как main.

Единственный гарантированный эффект inline заключается в том, что функция внешней связи может быть определена (одинаково) в двух или более единицах перевода, т. е. влияет на правило одного определения.

На практике это позволяет поместить определение в заголовочный файл, а его размещение в заголовочном файле также практически необходимо для обеспечения идентичных определений.

Это не имеет смысла для main, поэтому нет причин для main быть inline.

person Cheers and hth. - Alf    schedule 08.08.2011
comment
Нет никаких причин для того, чтобы main было inline убедительным, но не прямым объяснением того, почему это было сделано так, что оно не может быть помечено inline. - person Lightness Races in Orbit; 08.08.2011
comment
Я объяснил то же самое в своем ответе. Однако ваш вариант более проработан. - person iammilind; 08.08.2011
comment
Что ж, я думаю, стандарт не старается изо всех сил поддерживать то, что никто никогда не будет использовать. Но я думаю, кроме того, описание main не идеально. Например, я всегда думал и до сих пор считаю, что после первого утверждения основного бита в корне неверно. Но я нигде не видел, чтобы это обсуждалось. Может быть, это просто мое несовершенное понимание английского... - person Cheers and hth. - Alf; 08.08.2011
comment
@anonymous downvoters: пожалуйста, объясните причины, по которым вы понизили голосование, чтобы другие могли извлечь пользу из ваших идей (хе-хе). - person Cheers and hth. - Alf; 10.08.2011
comment
@Alf: В том же духе стандарт не изо всех сил запрещает что-либо, если для этого нет надлежащей причины. :) - person Lightness Races in Orbit; 11.08.2011
comment
Я не согласен с тем, что нет смысла определять main в заголовке. Существует довольно много библиотек/фреймворков, которые включают реализацию main, которая при связывании косвенно вызывает ваш код. Априори я не вижу существенной разницы между этим и определением main в заголовке. - person Tim Seguine; 06.10.2016
comment
@TimSeguine: я согласен с тем, что имеет смысл поместить main в заголовок, предназначенный для включения только в одну единицу перевода. На самом деле я так и сделал (пример на github). Но тогда не имеет смысла гарантировать идентичные определения в нескольких единицах перевода. Как я понимаю, никакая другая причина для inline не применима. - person Cheers and hth. - Alf; 07.10.2016
comment
Что-то вроде гарантированного сворачивания COMDAT может быть полезным. Но поскольку стандарт не гарантирует этого, я должен признать, что вы правы. - person Tim Seguine; 07.10.2016
comment
Запрет на то, чтобы main был встроенным, способствовал тому, что новые встраиваемые системы используют точку входа с другим именем. Например. цикл() или запуск(). Потому что там компилятор по своей сути встраивает код программы в образ ядра. - person Swift - Friday Pie; 01.11.2018

Вы можете определить main только один раз. Таким образом, установка inline не будет служить никакой цели - inline имеет важное значение только для функций, которые вы можете определить несколько раз в программе (все определения будут обрабатываться так, как если бы было только одно определение, и все определения должны быть одинаковыми).

Поскольку inline функции могут быть определены в программе несколько раз, а inline также служит для максимально быстрого вызова функции, помеченной inline, Стандарт требует, чтобы inline функции определялись в каждой единице перевода, в которой он используется. Таким образом, компиляторы обычно отбрасывают определение функции, если оно inline и функция не использовалась кодом в текущей единице перевода. Делать это для main было бы совершенно неправильно, что показывает, что inline и семантика main совершенно несовместимы.

Обратите внимание, что вопрос в вашем заголовке "Почему main() в C++ не может быть встроен?" и утверждение, которое вы цитируете из Стандарта, касается разных вещей. Вы спрашиваете, может ли функция быть встроена, что обычно понимается как вставка кода вызываемой функции полностью или частично в вызывающую функцию. Просто пометка функции inline вовсе не означает встраивания этой функции. Это полностью решение компилятора, и, конечно, если вы никогда не вызываете main (и вы не можете этого сделать), тогда нечего встраивать.

person Johannes Schaub - litb    schedule 08.08.2011
comment
Терминология в стандарте немного неудобна, но, несмотря на то, что встроенная функция может быть определена несколько раз, все определения должны быть идентичными, а поведение кода должно быть таким, как если бы оно было определено только один раз. (Тот факт, что встроенная функция должна быть определена в каждой единице перевода, которая ее использует, немного более проблематичен. Единственная единица перевода, которая будет ее использовать, — это та, которую вы не написали, она поставляется уже скомпилированной с вашей системой.) - person James Kanze; 08.08.2011
comment
@James: замечание в скобках, да, но Реализации разрешено творить любую магию, которую она хочет. <г> - person Cheers and hth. - Alf; 09.08.2011
comment
@Alf Согласен, пока сохраняется наблюдаемое поведение. Но стандарт не требует такой магии; разрешение main быть встроенным потребует этого. Исторически C++ не любил магию. (Но это было до шаблонов.) - person James Kanze; 09.08.2011

Если вы подключили статически к CRT и включили некоторую компиляцию-встраивание во время компоновки (как в MSVC), возможно, это можно будет встроить.

Но на самом деле это не имеет смысла. Она будет вызвана один раз, и эти накладные расходы на вызов функции практически ничто по сравнению со всем остальным, что делается до выполнения первой строки в main.

...

К тому же, это простой способ заставить символ появляться в вашем исполняемом файле только один раз. :)

person Macke    schedule 08.08.2011

Существует ряд основных причин. По сути, main вызывается из базовой процедуры инициализации среды выполнения и только оттуда. Этот код был (очевидно) скомпилирован, не зная, что ваш main был встроен. Современные технологии компиляторов позволяют выполнять встраивание через границы модулей, но это расширенная функция, не поддерживаемая многими старыми компиляторами. И, конечно же, преимущества встраивания проявляются только тогда, когда функция вызывается очень часто; по определению main будет вызываться ровно один раз, ни больше, ни меньше.

person James Kanze    schedule 08.08.2011

Я вижу, что стандарт говорит об этом, но реальный практический ответ был бы таким же простым, как утверждение, что среда выполнения, добавляемая к каждой программе C и C++, должна вызывать некоторую точку в исполняемом файле. Эта функция должна иметь внешний символ (и адрес при выполнении), чтобы компоновщик мог найти ее для вызова в начале выполнения. Следовательно, вы не можете объявить его как inline, потому что встроенный компилятор не сгенерирует для него внешний символ.

person Diego Sevilla    schedule 09.08.2011
comment
Пометка функции inline не обязательно приводит к тому, что функция становится встроенной. - person Lightness Races in Orbit; 17.11.2012
comment
Функция inline имеет внешнюю связь, если только она не является функцией области видимости пространства имен, явно объявленной static. - person Cheers and hth. - Alf; 07.10.2016

Поскольку это функция main(), которая запускает выполнение, когда код компилируется в двоичный, все находится в самом main(). так что можно сказать, он уже встроен!

И да, использование inline для вашей программы на C++ незаконно, это больше касается синтаксиса!

person linuxeasy    schedule 08.08.2011

Для большинства комбинаций компилятор/архитектура функция main() в исходном коде становится достаточно нормальной функцией в конечном бинарном файле. Это только потому, что это удобно на этих архитектурах, а не потому, что стандарт говорит, что так должно быть.

В архитектурах с ограниченной памятью многие компиляторы, которые создают плоский двоичный файл (например, шестнадцатеричный формат intex) вместо контейнера, удобного для динамического компоновщика (например, elf или xcoff), оптимизируют весь шаблон, поскольку он будет просто раздуваться. Некоторые архитектуры вообще не поддерживают вызовы функций (на этих платформах возможно только ограниченное подмножество C++).

Чтобы поддерживать самое большое разнообразие таких архитектур и сред сборки, стандартные выборы сохраняют семантику main() максимально открытой, чтобы компилятор мог делать то, что подходит для самых разных платформ. Это означает, что многие функции, доступные в языке в целом, не могут применяться к запуску и завершению работы самого приложения.

Если вам нужно что-то вроде встроенного main() (или повторного входа, или любой другой необычной функции), вы, конечно, можете вызвать основную функцию как-то иначе:

inline int myMain(int argc, char **argv) { /* whatever */ }
int main(int argc, char **argv) { return myMain(argc, argv); }
person SingleNegationElimination    schedule 08.08.2011

По умолчанию встроенные функции имеют статическую область видимости. Это означает, что если мы объявим функцию main() как встроенную, ее область действия будет ограничена файлом, в котором она определена. Тем не менее, стартовая библиотека C (предоставляемая поставщиком компилятора) требует, чтобы «main» был глобальным символом. Некоторые компиляторы позволяют изменять функцию точки входа (например, main) с помощью флагов компоновщика.

person Venki    schedule 16.09.2011

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

person Santosh    schedule 10.08.2011
comment
Не существует переносимого способа вызова main в программе на C++, даже если это не inline. - person Flexo; 17.09.2011

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

person Interfere    schedule 08.08.2011
comment
В большинстве или, вероятно, во всех системах ОС не отвечает за вызов main. Вместо этого ОС вызывает точку входа для программы на уровне машинного кода. Для C и C++ эта точка входа обычно является функцией в библиотеке времени выполнения, которая, в свою очередь, выполняет различные операции по инициализации, затем вызывает main и, наконец, выполняет очистку (например, вызывает установленные обработчики выхода) и завершает работу. - person Cheers and hth. - Alf; 08.08.2011