Почему argc не является константой?
int main( const int argc , const char[] const argv)
As Эффективный C++ пункт#3 гласит: "используйте const, когда это возможно", я начинаю думать: "почему бы не сделать эти "постоянные" параметры const
"?.
есть ли какой-либо сценарий, в котором значение argc
изменения в программе?
7 ответов
в этом случае, история-это фактор. C определил эти входные данные как "не постоянные", а совместимость с (значительной частью) существующего кода C была ранней целью c++.
некоторые API UNIX, такие как getopt
, на самом деле манипулировать argv[]
, поэтому его нельзя сделать const
по этой же причине.
(в сторону: интересно, что хотя getopt
прототип предполагает, что он не будет изменять argv[]
но может изменить строки, на которые указывает, на странице руководства Linux это getopt
переставляет свои аргументы, и похоже, они знают, что ведут себя непослушно. На странице man в Open Group эта перестановка не упоминается.)
положить const
on 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 запуск программы
¶1 функция, вызываемая при запуске программы под названием
main
. Реализация объявляет нет прототип для этой функции. Он должен быть определен с типом возврата int и без параметры:int main(void) { /* ... */ }
или с двумя параметрами (далее именуемые -
argc
иargv
хоть какие-то имена могут быть используется, поскольку они являются локальными для функции в которые они объявлены):int main(int argc, char *argv[]) { /* ... */ }
или эквивалент;10) или каким-либо другим образом, определенным реализацией.
¶2 если они объявлены, параметры для
argc
обычно не является константой, потому что сигнатура функции для main()
до const
.
поскольку argc является переменной стека, ее изменение не повлияет ни на что, кроме обработки вашей собственной командной строки.
вы, конечно, вольны объявить его const
Если вы хотите.
топ-уровня const
на формальном аргументе не является частью типа функции. Вы можете добавить или удалить его, как вам нравится: это влияет только на то, что вы можете сделать с аргументом в реализации функции.
и argc
вы можете свободно добавить const
.
но argv
вы не можете сделать символьные данные const
без изменения сигнатуры функции. Это означает, что это не один из стандартных main
сигнатуры функций и не придется признаваться как
подпись main
является своего рода историческим артефактом из C
. Исторически C
не было const
.
однако, вы можете объявить параметр const
поскольку эффекты const-это только время компиляции.
, потому что argc
является локальной переменной (и, в C++, Не ссылкой или чем-то еще), а потому, что специальное место main
означает, что махинации с обратной совместимостью предоставляют ему огромное количество свободы действий без убедительных причин силу приложения, чтобы сделать его const.
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 non -const
заключается в том, что реализация компилятора не знает, что вы собираетесь делать с аргументами main, она просто знает, что она должна дать вам эти аргументы.
когда вы определяете свои собственные функции и связанные прототипы, вы знаете, какие параметры вы можете сделать const
и какие функции будут изменены.
доведенный до крайности, вы можете объявить, что все параметры для всех функций должны быть объявлены const
, а затем, если бы у вас была причина изменить их (например, уменьшить индекс для поиска по массиву), вам пришлось бы сделать локальный не-const
переменные и скопировать const
значения аргументов в эти переменные. Это делает для занят-работы и дополнительного LOC без реальной выгоды. Приличный статический анализатор подберет, если вы не изменяете значение аргумента, и порекомендует вам сделать параметр const
.