Почему argc не постоянный?

int main( const int argc , const char[] const argv)

Как Эффективный C++ Пункт # 3 состояния "Использование константного всякий раз, когда это возможно", я начинаю думать, "почему бы не сделать этот„постоянные“параметры const?".

Есть ли сценарий, в котором значение argc изменяется в программе?

Ответ 1

В этом случае история является фактором. C определили эти входы как "не постоянные", а совместимость с (хорошей частью) существующего кода C была ранней целью С++.

Некоторые API-интерфейсы UNIX, такие как 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, и я знаю, что я не одинок. Я скопировал пример откуда-то.

Ответ 2

В стандарте 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 Если они объявлены, параметры функции 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 должны быть модифицируемыми. Их не нужно изменять, но они могут быть изменены.

Ответ 3

argc обычно не является константой, потому что сигнатура функции для main() предшествует const.

Поскольку argc - это переменная стека, ее изменение не будет влиять ни на что иное, кроме вашей собственной обработки командной строки.

Вы, конечно, можете объявить его const, если хотите.

Ответ 4

Верхний уровень const в формальном аргументе не является частью типа функции. Вы можете добавить его или удалить его по своему усмотрению: он влияет только на то, что вы можете сделать с аргументом в реализации функции.

Итак, для argc вы можете свободно добавить const.

Но для argv вы не можете создавать символьные данные const, не изменяя при этом подпись функции. Это означает, что он не является одной из стандартных сигнатур функций main и не должен быть распознан как функция main. Итак, не очень хорошая идея.


Хорошей причиной для использования стандартных аргументов main в программах, отличных от игрушек, является то, что в Windows они не могут представлять фактические аргументы программы, такие как имена файлов с международными символами. Это потому, что в Windows это очень сильное соглашение, закодированное как Windows ANSI. В Windows вы можете реализовать еще несколько возможностей доступа к портативным аргументам в терминах функции GetCommandLine API.


Подводя итог, ничто не мешает вам добавить const в argc, но самая полезная const -ness на argv даст вам нестандартную main функцию, скорее всего, не распознанную как таковую, К счастью (по иронии) есть веские причины не использовать стандартные аргументы main для переносимого серьезного кода. Достаточно просто, для практической работы они поддерживают только старый ASCII, имея только буквы английского алфавита.

Ответ 5

Подпись main представляет собой несколько исторический артефакт из C. Исторически C не имел const.

Однако вы можете объявить свой параметр const, поскольку эффекты const являются только временем компиляции.

Ответ 6

Потому что argc - это локальная переменная (и в С++, а не ссылка или что-то еще), а потому, что особое место main означает, что обратная совместимость shenanigans предоставляет ему огромную свободу действий без каких-либо веских оснований заставить приложения сделать его 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 и С++.

Итак, в конце концов, это не то, что argc не const, просто это не обязательно, но может быть, если вы хотите, чтобы это было.

http://ideone.com/FKldHF, например:

main(const int argc, const char* argv[]) { return 0; }

http://ideone.com/m1qc9c, пример С++

main(const int argc) {}

Ответ 7

Помимо исторических причин, хорошей причиной для поддержания argc и argv не const является то, что реализация компилятора не знает, что вы собираетесь делать с аргументами main, она просто знает, что она должна дайте вам эти аргументы.

Когда вы определяете свои собственные функции и связанные с ними прототипы, вы знаете, какие параметры вы можете сделать const, а какие из них будут изменять ваша функция.

В крайнем случае вы можете объявить, что все параметры для всех функций должны быть объявлены const, а затем, если у вас есть причина их изменения (например, уменьшение индекса для поиска по массиву), вы должны иметь сделать локальные переменные const и скопировать значения аргументов const в эти переменные. Это делает занятие работой и дополнительным LOC без реальной выгоды. Если вы не изменяете значение аргумента, вы получите достойный статический анализатор и попробуйте сделать параметр const.