Могут ли аргументы сигнатуры main в C++ иметь квалификаторы unsigned и const?
Стандарт прямо заявляет, что main
имеет две действительные (т.е. гарантированно работающие) подписи; а именно:
int main();
int main(int, char*[]);
Мой вопрос прост, будет ли что-то вроде следующего законным?
int main(const unsigned int, const char* const* argv);
Мои тесты говорят "да", но я не уверен в ответе, потому что я не перегружен main
путем изменения int
в unsigned int
а также не верхнего уровня const
-очность аргв? Если я, то это явно запрещено.
Итак, гарантированно ли работают эти модификации на компиляторе, соответствующем стандартам?
7 ответов
Стандарт C++98 гласит в разделе 3.6.1 параграф 2
Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Должен иметь тип возврата типа
int
, но в остальном его тип определяется реализацией. Все реализации должны позволять оба следующих определенияmain
:int main()
а такжеint main(int argc, char* argv[])
Так что это не предписано стандартом, который принимает env main
приемлемо, но допустимо.
Поскольку это часто упоминается, здесь приведен предыдущий абзац, освобождающий автономные среды от всего, кроме документирования их поведения:
Программа должна содержать глобальную функцию main, которая является назначенным началом программы. Это реализация, определяемая, требуется ли программе в автономной среде для определения главной функции. [Примечание: в автономной среде запуск и завершение определяются реализацией; автозагрузка содержит выполнение конструкторов для объектов области пространства имен со статической продолжительностью хранения; Завершение содержит выполнение деструкторов для объектов со статической длительностью хранения. ]
Вы должны использовать одну из подписей, соответствующих стандарту, чтобы соответствовать стандарту.
Я полностью понимаю, почему вы хотите сделать это по-своему. Лучший способ - написать свою собственную функцию myMain() или любую другую с нужной подписью и вызвать ее из main(), включая необходимые преобразования.
argv
указатели не должны быть const char* const
потому что программе разрешено менять буферы.
Насколько я вижу из прочтения стандарта, вы не соответствует стандартам. Но я не могу представить компилятор, который не позволил бы вам сделать это. Например, компилятору потребовалось бы больше работы, чтобы конкретно запретить крайний случай, который в основном безвреден и очень неясен.
Это может не работать, если компилятор использует искажение имени для main
, В конце концов, это функция C++. Следовательно, компоновщик будет искать два конкретных "искажения". Ваше определение будет иметь другое искаженное имя.
Обратите внимание, что main
является особенным (не перегружается, не вызывается) и может вообще не требовать искажения имени.
Вы можете быть незаконным по стандарту, но большинство сред выполнения на самом деле не заботятся. Они просто нажмут целое число для argc
и указатель для argv
позвони main
и надеюсь, что вы разберете их правильно. Итак, с вашей точки зрения, "гарантированная работа" спорна, так как загрузчику действительно все равно, как вы объявили аргументы.
Если он строит, main
будет вызван. Как вы анализируете аргументы, зависит от вас. Я должен уточнить, что это очень зависит от платформы, как и почти весь этот вопрос.
Тем не менее, почему?
ISO/IEC 9899:TC3
Раздел 5.1.2.2.1 Запуск программы
Функция, вызываемая при запуске программы, называется основной. Реализация не объявляет прототип для этой функции. Он должен быть определен с типом возврата int и без параметров:
int main(void) { /* ... */ }
или с двумя параметрами (именуемыми здесь как argc и argv, хотя могут использоваться любые имена, так как они являются локальными для функции, в которой они объявлены):
int main(int argc, char *argv[]) { /* ... */ }
или эквивалентный;9) или каким-либо другим способом, определяемым реализацией.