Почему 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.