Почему argc не является константой?

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

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

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

101

Решение

В этом случае история является фактором. 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, и я знаю, что я не одинок. Я скопировал пример с где-то.

113

Другие решения

Стандарт 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 должен быть изменяемым. Они не должны быть изменены, но они могут быть изменены.

37

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

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

Вы, конечно, свободны заявить об этом const если ты хочешь.

24

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

Таким образом, для argc Вы можете добавить свободно добавить const,

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


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


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

9

Подпись main является своего рода историческим артефактом C, Исторически C не имел const,

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

5

Так как 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) {}
3

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

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

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

1
По вопросам рекламы [email protected]