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

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