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