Правовые определения main() в C++14

Последний черновик C++14, который мне удалось найти, говорит о main() [3.6.1]:

Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь возвращаемый тип типа int, но в остальном его тип определяется реализацией. Все реализации должны позволять

- функция (), возвращающая int и

- функция (int, указатель на указатель на символ), возвращающая int

и (пункт 5)

Если управление достигает конца main, не встречая оператора return, эффект заключается в выполнении

return 0;

Означает ли это, что все перечисленные ниже являются легальными минимальными программами на C++14? Если нет, то почему бы и нет?

  1. auto main() -> int {}
  2. auto main() { return 0; }
  3. auto main() {}

2 ответа

Решение
  1. Законно, второе и последнее не по следующим причинам:

  2. Тип возврата основной функции не может быть выведен, так как CWG 1669 был принят, и стандарт будет переписан как:

    Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь объявленный возвращаемый тип типа int, но в остальном его тип определяется реализацией.

    Это вошло в n4140. Подробнее об этом: http://wg21.cmeerw.net/cwg/issue1669

  3. Так же, как выше

Первое, вероятно, законно. Другие два, конечно, не (§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 заменяется "либо вычетом из инициализатора, либо явной спецификацией с типом конечного возврата". (И, конечно, функции не имеют инициализаторов, поэтому может применяться только конечный тип возврата.) Однако в последующих параграфах говорится о вычете из возвращаемого типа, даже если в первом абзаце требуется конечный тип возврата (и таким образом делает удержание излишним).

Другие вопросы по тегам