int main( const int argc , const char[] const argv)
Как Эффективный C ++ Пункт № 3 гласит: «Используйте const всякий раз, когда это возможно», я начинаю думать, почему бы не сделать эти «постоянные» параметры const
?».
Есть ли сценарий, в котором значение argc
модифицируется в программе?
В этом случае история является фактором. C определил эти входные данные как «не константные», и совместимость (существенная часть) с существующим кодом C была ранней целью C ++.
Некоторые UNIX API, такие как getopt
на самом деле манипулировать argv[]
так что это не может быть сделано const
по этой причине также.
(В сторону: интересно, хотя getopt
Прототип предполагает, что он не изменится argv[]
но может изменить строки, на которые указывает ссылка, страница руководства Linux указывает, что getopt
переставляет свои аргументы, и кажется, они знают, что они непослушные. Страница руководства в Open Group не упоминает эту перестановку.)
Ввод const
на argc
а также argv
не будет покупать много, и это лишит законной силы некоторые практики программирования старой школы, такие как:
// print out all the arguments:
while (--argc)
std::cout << *++argv << std::endl;
Я написал такие программы на C, и я знаю, что я не одинок. Я скопировал пример с где-то.
Стандарт C (ISO / IEC 9899: 2011) гласит:
5.1.2.2.1 Запуск программы
Called1 Функция, вызываемая при запуске программы, называется
main
, Реализация заявляет нет
прототип для этой функции. Он должен быть определен с типом возврата int и без
параметры:int main(void) { /* ... */ }
или с двумя параметрами (упоминается здесь как
argc
а такжеargv
хотя могут быть любые имена
используется, поскольку они являются локальными для функции, в которой они объявлены):int main(int argc, char *argv[]) { /* ... */ }
или эквивалент;10) или каким-либо другим способом, определяемым реализацией.
If2 Если они объявлены, параметры к
main
функция должна подчиняться следующему
ограничения:
- Значение
argc
должен быть неотрицательным.argv[argc]
должен быть нулевым указателем.- Если значение
argc
больше нуля, члены массиваargv[0]
через
argv[argc-1]
включительно должен содержать указатели на строки, которые даны
определенные реализацией значения хост-средой до запуска программы.
намерение состоит в том, чтобы предоставить программе информацию, определенную до запуска программы
из другого места в размещенной среде. Если среда хоста не способна
предоставление строк с буквами в верхнем и нижнем регистре, реализация
убедитесь, что строки получены в нижнем регистре.- Если значение
argc
больше нуля, строка указанаargv[0]
представляет название программы;argv[0][0]
должен быть нулевым символом, если
Имя программы недоступно из среды хоста. Если значениеargc
является
больше единицы строки, на которые указываетargv[1]
черезargv[argc-1]
представляют параметры программы.- Параметры
argc
а такжеargv
и строки, на которые указываетargv
массив должен
быть изменяемыми программой и сохранять их последние сохраненные значения между программами
запуск и завершение программы.10) Таким образом,
int
может быть заменено именем typedef, определенным какint
или типargv
можно записать как
char **argv
, и так далее.
Обратите внимание на последнюю точку маркера. Это говорит о том, что оба argc
а также argv
должен быть изменяемым. Они не должны быть изменены, но они могут быть изменены.
argc
обычно не является константой, потому что сигнатура функции для main()
предварительные даты const
,
Поскольку argc является переменной стека, ее изменение не повлияет ни на что, кроме обработки вашей собственной командной строки.
Вы, конечно, свободны заявить об этом const
если ты хочешь.
Верхний уровень const
на формальный аргумент не является частью типа функции. Вы можете добавить или удалить его как хотите: это влияет только на то, что вы можете сделать с аргументом в реализации функции.
Таким образом, для argc
Вы можете добавить свободно добавить const
,
Но для argv
Вы не можете сделать данные персонажа const
тем самым не меняя сигнатуру функции. Это означает, что это тогда не один из стандартных main
подписи функций, и не должны быть распознаны как main
функция. Так что не очень хорошая идея.
Хорошая причина не использовать стандарт main
Аргументы в не игрушечных программах в том, что в Windows они не могут представлять фактические аргументы программы, такие как имена файлов, с международными символами. Это потому, что в Windows они по очень строгому соглашению закодированы как Windows ANSI. В Windows вы можете реализовать более переносимое средство доступа к аргументам с точки зрения GetCommandLine
API-функция.
Подводя итог, ничто не мешает вам добавить const
в argc
, но самый полезный const
-несс на argv
даст вам нестандартный main
функция, скорее всего, не признается как таковая. К счастью (иронично), есть веская причина не использовать стандарт main
аргументы в пользу переносимого серьезного кода. Проще говоря, на практике они поддерживают только старый ASCII, только с буквами английского алфавита.
Подпись main
является своего рода историческим артефактом C
, Исторически C
не имел const
,
Тем не менее, вы можете объявить свой параметр const
так как эффекты const только время компиляции.
Так как argc
является локальной переменной (и, в C ++, не ссылка или что-то), и потому что особое место main
означает, что махинации с обратной совместимостью предоставляют ей огромную свободу действий без веских причин сила приложения, чтобы сделать его постоянным.
main() {}
int main() {}
main() { return 0; }
main(int argc, char* argv[]) { return 0; }
int main(const int argc, const char** argv) { /* no return*/ }
эти и многие другие варианты будут компилироваться в широком диапазоне компиляторов C и C ++.
Так что, в конечном счете, дело не в том, что argc не const, а в том, что так не должно быть, но это может быть, если вы этого хотите.
http://ideone.com/FKldHF, C пример:
main(const int argc, const char* argv[]) { return 0; }
http://ideone.com/m1qc9c, Пример C ++
main(const int argc) {}
Помимо исторических причин, есть веская причина оставить argc и argv неconst
в том, что реализация компилятора не знает, что вы собираетесь делать с аргументами main, она просто знает, что должна дать вам эти аргументы.
Когда вы определяете свои собственные функции и связанные с ними прототипы, вы знаете, какие параметры вы можете сделать const
и какие из них ваша функция будет изменять.
В крайнем случае, вы можете объявить, что все параметры для всех функций должны быть объявлены const
и затем, если у вас была причина изменить их (например, уменьшить индекс для поиска в массиве), вам придется сделать локальныйconst
переменные и скопировать const
значения аргументов в эти переменные. Это делает для занятой работы и дополнительного LOC без реальной выгоды. Приличный статический анализатор подберет, если вы не изменяете значение аргумента, и порекомендует вам сделать параметр const
,