Является ли использование main без возвращаемого типа в С++ 11?
Стивен Прата в своей книге С++ Primer Plus [стр. 31] говорит:
Многие существующие программы вместо этого используют классический заголовок функции C:
main() // original C style
В классическом C, опуская тип возврата это то же самое, что сказать, что функция - это тип int. Однако С++ имеет отмените это использование.
Однако в проекте С++ 11 3.6.1- > 2 говорится
Реализация не должна предопределять основную функцию. Эта функция не должны быть перегружены. Он должен иметь тип возвращаемого типа int, но в противном случае его тип определяется реализацией.
Результат теста
$ g++ -Werror=pedantic MainCheck.cpp -o MainCheck
MainCheck.cpp:3:6: error: ISO C++ forbids declaration of ‘main’ with no type [-Werror=pedantic]
main()
$ # also means g++ don't conform to the standard
подтверждает, что г-н Прата сказал, что это правда, когда дело доходит до стандарта С++.
Есть ли предложение в проекте С++ 11, которое препятствует использованию:
main() // that is without return type.
Есть
Он должен иметь тип возврата типа int
сам такой пункт?
Ответы
Ответ 1
См. также Что должно main()
вернуться на C и С++?
ISO/IEC 14882: 1998 содержит:
§7 Объявления
¶7 Только в объявлениях функций для конструкторов, деструкторов и преобразований типов может быть спецификатор decl-specifier-seq опускаем. 78)
и в сноске 78 говорится:
Правило "неявного int" для C больше не поддерживается.
Те же утверждения содержатся в ¶9 и сноске 89 в стандарте С++ 11.
Итак, main()
, объявленный без возвращаемого типа, никогда не был частью стандартного С++, но он был разрешен примерно до тех пор, пока не был создан стандарт С++ 98 (и, вероятно, немного длиннее по соображениям обратной совместимости).
Если вы посмотрите в Struustrup "Дизайн и эволюция С++" (опубликовано в 1994 году), §2.8 Синтаксис декларации C гласит:
Разрешить опускание спецификатора типа (что означает int
по умолчанию) также привело к осложнениям.... Отрицательная реакция на изменения в этой области от пользователей была очень сильной.... Я отменил это изменение. Я не думаю, что у меня был выбор. Разрешение того, что неявный int
является источником многих раздражающих проблем с грамматикой С++ сегодня.... Наконец, десять лет спустя, стандартный комитет CSI ANSI/ISO решил отказаться от неявного int
. Это означает, что мы можем избавиться от него в другое десятилетие или около того.
Ответ 2
Неявные типы int
были запрещены во всех стандартах С++, то есть в С++ 98 он не был разрешен. Это не что-то новое в С++ 11. Не было никакого исключения для main()
в отношении объявления функции. Кроме того, неявное правило int
применяется ко всем объявлениям не только к main()
.
Соответствующим предложением в стандарте С++ является 7 [dcl.dcl] пункт 11:
Только в объявлениях функций для конструкторов, деструкторов и преобразований типов можно указать decl-specifier-seq опускаем. 94
94) Правило "неявного int" для C больше не поддерживается.
У меня нет простого доступа к стандарту С++ 98 прямо сейчас, но С++ 03 определенно имеет тот же оператор. Единственное отличие состоит в том, что он находится в параграфе 7, а сноска - " 79" вместо " 94".
C неявное правило int
некоторое время было частью С++ до первого стандарта, но в какой-то момент его удалили. Компиляторы могут принимать программы, пропускающие тип в качестве расширения, но я думаю, что они должны испускать диагностику. Много ли это - отдельный вопрос, поскольку давно установлено, что запись одного \r
в начале строки соответствовала бы этому требованию.
Что есть, и что останется, это нечетное исключение, что выполнение программы может истечь в конце main()
без оператора return
: предполагается, что указание return
в main()
нарушит существующие код.
Утверждение
Он должен иметь тип возвращаемого типа int
ничего не говорит о том, как функция получает свой возвращаемый тип. В нем указывается только тип возврата.
Ответ 3
Это, что рабочий проект говорит об основной функции.
Выдержки следуют.
Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Его тип должен иметь ссылку на язык С++ и должен иметь объявленный тип возвращаемого типа int, но в противном случае его тип определяется реализацией. Реализация должна обеспечивать как
- функция(), возвращающая int и
- функция (int, указатель на указатель на char), возвращающая int
как тип основного
Оператор возврата в основном имеет эффект выхода из основной функции [...] Если управление течет с конца составного оператора main, эффект эквивалентен возврату с операндом 0
Итак, стандарт говорит, что основная функция должна иметь один из следующих типов:
Являясь главной функцией функции, я предполагаю, что она также соответствует правилам в 8.3.5.
Вопрос будет таким: можно ли опустить тип возвращаемого значения из определения функции? Стандарт позволяет мне это сделать?
Ответ - нет.
Ответ 4
Стандарт для main
не требуется явно возвращать. Если инструкция return
отсутствует, компилятор просто ставит:
return 0;
в конце. Это правило не применяется к другим функциям.
В C по умолчанию возвращаемый тип любой функции был int
, если не предоставлен программистом, например:
get() // int assumed
{
return 10;
}
Стандарт С++ требует указания типа возврата. Выше код не будет компилироваться в компиляторе С++. C90 допускает неявный int
, C99 запрещает неявный int
.