Правовые определения main() в C++14
Последний черновик C++14, который мне удалось найти, говорит о main()
[3.6.1]:
Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь возвращаемый тип типа int, но в остальном его тип определяется реализацией. Все реализации должны позволять
- функция (), возвращающая int и
- функция (int, указатель на указатель на символ), возвращающая int
и (пункт 5)
Если управление достигает конца main, не встречая оператора return, эффект заключается в выполнении
return 0;
Означает ли это, что все перечисленные ниже являются легальными минимальными программами на C++14? Если нет, то почему бы и нет?
auto main() -> int {}
auto main() { return 0; }
auto main() {}
2 ответа
Законно, второе и последнее не по следующим причинам:
Тип возврата основной функции не может быть выведен, так как CWG 1669 был принят, и стандарт будет переписан как:
Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь объявленный возвращаемый тип типа int, но в остальном его тип определяется реализацией.
Это вошло в n4140. Подробнее об этом: http://wg21.cmeerw.net/cwg/issue1669
Так же, как выше
Первое, вероятно, законно. Другие два, конечно, не (§7.1.6.4/1): "Автоматический спецификатор типа означает, что тип объявленной переменной должен быть выведен из ее инициализатора или что декларатор функции должен включать в себя тип конечного возврата".
Я говорю, вероятно, для первого, потому что §3.6.1 не совсем ясно, в какой степени определение должно соответствовать. 100% текстовое совпадение не требуется, даже если это то, что подразумевает буквальное толкование того, что оно говорит: в тексте текст main
дается как /* ... */
, что не очень полезно, и, конечно, не требуется. Точно так же традиция также позволила любое имя для argc
а также argv
и объявив argv
как char** argv
, Однако не существует традиции определения main с помощью типа трейлинг-возврата. Я думаю, что в §3.6.1 подразумевалось, что все определения main
которые имеют одинаковую подпись, будет разрешено, но это не то, что говорят реальные слова.
Независимо от того: зачем нужно такое запутывание? C/C++ не является Pascal, а то, что естественно в одном языке (например, завершающие типы возврата для функций), является запутанностью в другом.
РЕДАКТИРОВАТЬ:
Я только что скачал более свежий черновик (N3797), и похоже, что формулировка изменилась (и теперь противоречива). Первый абзац все еще говорит в основном то же самое (но включает дополнительную формулировку для лямбд): auto
заменяется "либо вычетом из инициализатора, либо явной спецификацией с типом конечного возврата". (И, конечно, функции не имеют инициализаторов, поэтому может применяться только конечный тип возврата.) Однако в последующих параграфах говорится о вычете из возвращаемого типа, даже если в первом абзаце требуется конечный тип возврата (и таким образом делает удержание излишним).