Ответ 1
TL;DR. Вызов main
приводит к поведению undefined.
Похоже, что существует путаница в терминологии, используемой в стандарте, и о последствиях для программиста и компилятора.
Во-первых, стандарт самостоятельно определяет все, что касается языка С++. Если ваша конкретная версия конкретного компилятора допускает какое-то конкретное действие, которое не имеет никакого отношения к тому, является ли это действие законным. Для остальной части сообщения я имею в виду стандарт ISO03.
Итак, чтобы еще раз процитировать, стандарт гласит в п. 3.3.1.3:
Функция main не должна использоваться внутри программы.
Кроме того, в §3.2 "используется" как:
Объект или неперегруженная функция используется, если его имя отображается в потенциально вычисленном выражении.
Это означает, что, как только программа начнет выполнение, main
должен никогда не вводиться снова. Это означает, что программисты не могут вызывать main
, это значит, что компилятор не может вставить другой вызов main
(почему он будет, кто знает), вы не можете взять адрес main и позвонить, и т.д. У вас даже не может быть потенциала вызов main
.
Единственный вызов main
должен выполняться библиотекой времени выполнения, в которой запущена программа; все остальные вызовы вызывают поведение undefined. (Это означает, что все может случиться!)
Теперь о поведении компилятора:
Диагностическое правило определяется как (§1.4.1):
Набор диагностируемых правил состоит из всех синтаксических и семантических правил в этом Международном стандарте, за исключением тех правил, которые содержат явное обозначение, что "никакой диагностики не требуется" или которые описаны как результат "undefined поведения".
В нашем случае в п. 3.3.1.3 определяется правило диагностики. Вот какие компиляторы должны делать в соответствии с §1.4.2:
- Если программа не содержит нарушений правил в этом Международном стандарте, соответствующая реализация должна в пределах своих ресурсов принимать и правильно выполнять3) эту программу.
- Если программа содержит нарушение любого диагностируемого правила, соответствующая реализация должна выпустить хотя бы одно диагностическое сообщение, за исключением того, что - Если программа содержит нарушение правила, для которого не требуется диагностика, настоящий международный стандарт не устанавливает требований к реализации в отношении этой программы.
Поэтому компиляторы не обязаны применять правила. Все компиляторы должны сделать, это взять хорошо сформированные программы (§1.3.14) и превратить их в исполняемую программу. Компилятор может свободно предупреждать, ошибочно и т.д., Однако ему нравится, если он не конфликтует с языком. В соответствии со вторым предложением необходимо отобразить сообщение в нашем конкретном случае.
Для этой конкретной задачи на gcc параметр -pedantic
будет предупреждать о незаконности вызова main
внутри программы. Visual Studio не будет предупреждать о вызове main
, но на любом уровне предупреждения (больше 0) он будет предупреждать о рекурсивном характере программы.
Что все это означает с точки зрения ответов, которые вы должны ожидать? Это означает, что совершенно бессмысленно пытаться определить с уверенностью то, что опубликует фрагмент кода. Вызов main
приводит к поведению undefined, и попытка определения поведения undefined, очевидно, является потерянной причиной. Единственный честный ответ, который любой может дать "что происходит, когда я называю main
?"? "Что угодно".
Надеюсь, это прояснит ситуацию.