Могут ли аргументы основной подписи на С++ иметь 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) или каким-либо другим способом реализации.