2009-10-25 6 views
24

В стандарте указано, что main имеет две действующие (то есть гарантированные работы) сигнатуры; а именно:Могут ли аргументы основной подписи на C++ иметь unsiged и const qualifiers?

int main(); 
int main(int, char*[]); 

Мой вопрос прост, будет ли что-то вроде следующего быть законным?

int main(const unsigned int, const char* const* argv); 

Мои тесты говорят «да», но я не уверен в ответе, потому что я не перегружать main путем изменения int к unsigned int, а также отсутствия верхнего уровня const -ness из ARGV? Если я, то это явно запрещено.

Итак, эти модификации гарантированно работают на совместимый с стандартами компилятор?

+7

Почему вы хотите сделать что-то подобное? Просто напишите стандартно-совместимый код – Glen

+10

Glen, I _want_, чтобы написать соответствующий код. Вот почему я задал этот вопрос в первую очередь. – bh9042

+9

Затем объявите 'int main (int, char **)' и будьте на своем пути. –

ответ

33

стандарт C++ 98 говорит, что в разделе 3.6.1 пункта 2

Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь тип возврата типа int, но в противном случае его тип определяется реализацией. Все реализации должны позволять как следующие определения main: int main() и int main(int argc, char* argv[])

Так что это не предусмотрено стандартом, что окр принятие main является приемлемым, но это допустимо.


Поскольку это упоминается часто, здесь предыдущий пункт освобождающего Корпусной среды от чего-либо, но документировать их поведение:

Программа должна содержать глобальную функцию, называемую основными, который является назначенным началом программы. Реализация определена , требуется ли программа в автономной среде для определения основной функции .[Примечание: в автономной среде, запуск и завершение реализации; startup содержит выполнение конструкторов для объектов пространства пространств имен со статической продолжительностью хранения; завершение содержит выполнение деструкторов для объектов со статической продолжительностью хранения. ]

+0

Ах, я пропустил часть «типа», когда прочитал. – bh9042

1

Насколько я вижу из чтения стандарта, вы не соблюдаете стандарты. Но я не могу представить себе компилятор, который бы не позволял вам делать это. Как и в случае, потребуется больше работы от компилятора, чтобы конкретно запретить кейс с краем, который является в основном безвредным и очень неясным.

+0

Аминь. ваш код МОЖЕТ иметь проблемы с компиляцией на гипотетическом компиляторе, который соответствует 100% стандарту. Но большинство компиляторов этого не делают, и этот краевой случай, вероятно, является одним из тех, где они допускают технически незаконное поведение. – DVK

2

Указатели argv не должны быть const char* const, потому что программе разрешено изменять буферы.

+0

** Только ** строки, а не указатели на строки. –

+3

В этом суть. Я не хочу ничего менять! – bh9042

+2

Тогда ничего не меняйте. –

0

Возможно, вы можете быть незаконными по стандарту, но большинство времени работы на самом деле все равно. Они просто нажмут целое число для argc и указатель на argv, позвоните по телефону main и надейтесь, что вы разобрали их правильно. Таким образом, в вашей компетенции «гарантировано работать» является спорным, поскольку загрузчику действительно не важно, что вы объявили как аргументы.

Если он строит, то будет вызван main. Как вы разбираете аргументы, зависит от вас. Я должен уточнить, что это очень специфично для платформы, поскольку это почти весь этот вопрос.

Что сказал, Почему?

+1

1. argc гарантированно будет неотрицательным, я хочу увидеть без знака где-то там ...;) 2. Я хочу, чтобы дополнительная защитная сетка, которую const предоставляет против глупых ошибок. Как я ответил на jeffamaphone, хотя мне разрешено менять argv, я не хочу или не хочу. – bh9042

+1

'main' предшествует C++ и даже время' unsigned'. Независимо от того, что вы хотите, 'main' был объявлен таким образом в течение долгого времени. Вам действительно нужен компилятор, чтобы защитить вас от изменения «argv»? Если у вас нет этого 'const', вы случайно замените все '-' на '/' в строках' argv'? Вы не продаете меня, почему это необходимо. –

+1

Я думаю, что это допустимая точка, позволяющая программистам указывать предположения и ограничения с помощью таких модификаторов, как 'unsigned' и' const'. Если это хорошо для пользовательских функций, я не понимаю, почему это не было бы хорошо для 'main()' тоже. –

19

Вы должны использовать одну из стандартно-совместимых подписей, чтобы быть стандартно-совместимыми.

Я полностью понимаю, почему вы хотите сделать это по-своему. Лучший способ - написать свою собственную функцию myMain() или что угодно с подписью, которую вы хотите, и назвать ее из main(), включая требуемые роли.

+5

+1 для предоставления полезного ответа вместо всех остальных «Я не понимаю, зачем вы это делаете». –

1

Это может не сработать, если компилятор использует имя mangling для main. В конце концов, это C++. Следовательно, компоновщик будет искать два конкретных «искажения». У вашего определения будет другое искаженное имя.

Обратите внимание, что main является специальным (не перегружает, не может быть вызвано) и может вообще не требовать колличества имен.

0

ISO/IEC 9899: ТС3

Раздел 5.1.2.2.1 Запуск программ

Функция называется при запуске программы называется основной. Реализация объявляет прототип для этой функции. Она должна быть определена с типом возвращаемого междунар и без каких-либо параметров:

int main(void) { /* ... */ } 

или с двумя параметрами (именуемых здесь как ARGC и ARGV, хотя любые имена могут быть использованы , так как они являются локальными в функция, в которой они заявлены):

int main(int argc, char *argv[]) { /* ... */ } 

или аналогичный вариант 9) или каким-либо другим способом реализации.