int main( const int argc , const char[] const argv)
Поскольку в пункте № 3 эффективного C ++ сказано: «По возможности используйте const», я начинаю думать: «Почему бы не сделать эти« постоянные »параметры const
?».
Есть ли какой-нибудь сценарий, при котором значение argc
изменяется в программе?
argc
какconst
.--argc
const
; действительно, передачаargc
какconst int
средство, которое вы не можете затем использоватьargc
, скажем, как счетчик внутри функции.const
использования параметра передачи по значению ничего не получится . См., Например, stackoverflow.com/a/8714278/277304 и stackoverflow.com/a/117557/277304Ответы:
В этом случае история играет важную роль. C определил эти входные данные как «непостоянные», и совместимость с (значительной частью) существующего кода C была ранней целью C ++.
Некоторые API-интерфейсы UNIX, например
getopt
, действительно манипулируютargv[]
, поэтому это невозможно сделать иconst
по этой причине.(В сторону: интересно, хотя
getopt
прототип предполагает, что он не будет изменять,argv[]
но может изменять строки, на которые указывает, страница руководства Linux указывает, чтоgetopt
переставляет свои аргументы, и, похоже, они знают, что они непослушны . Страница руководства на Open Группа не упоминает об этой перестановке.)Положив
const
наargc
иargv
не будет покупать много, и это может сделать недействительными некоторые старой школы программирования практики, такие как:Я написал такие программы на C и знаю, что не одинок. Я скопировал откуда- то пример .
источник
const
кargv
, не влияя на то , что любая функция C может сделать. Такжеgetopt
заявлен какint getopt(int argc, char * const argv[], const char *optstring);
. И здесьconst
это не верхний уровень, но объявляет указателиconst
, обещание не изменять их (хотя строки, на которые они указывают, могут быть изменены).char* const* ___argv
там есть, но интерфейс действительно соответствуетconst char **
. Такая путаница. Я перепутал приоритетность[]
и по*
отношению кconst
. Мои извинения.getopt()
знает, что он не следует стандарту, потому что он обращает внимание наPOSIXLY_CORRECT
переменную среды, чтобы она работала правильно. В частности, POSIX не переставляет аргументы и не ищет параметры после первого аргумента, не являющегося параметром.Стандарт C (ISO / IEC 9899: 2011) гласит:
Обратите внимание на последний пункт. В нем говорится, что и то
argc
и другоеargv
должно быть изменяемым. Их не нужно изменять, но они могут быть изменены.источник
QApplication(argc,argv)
конструктор Qt был определен сargc
помощью ссылки . Это меня удивило.argc
обычно не является константой, потому что подпись функции дляmain()
предварительных датconst
.Поскольку argc является переменной стека, ее изменение не повлияет ни на что, кроме обработки вашей собственной командной строки.
Вы, конечно, можете заявить об этом,
const
если хотите.источник
Верхний уровень
const
формального аргумента не является частью типа функции. Вы можете добавить или удалить его по своему усмотрению: он влияет только на то, что вы можете делать с аргументом в реализации функции.Так что
argc
вы можете свободно добавлятьconst
.Но ведь
argv
вы не можете создать символьные данные,const
не изменив тем самым сигнатуру функции. Это означает, что тогда это не одна из стандартныхmain
сигнатур функции, и ее не нужно будет распознавать какmain
функцию. Итак, не лучшая идея.Хорошая причина не использовать стандартные
main
аргументы в программах, не являющихся игрушечными, заключается в том, что в Windows они не могут представлять фактические аргументы программы, такие как имена файлов с международными символами. Это потому, что в Windows они очень строго кодируются как Windows ANSI. В Windows вы можете реализовать еще несколько переносимых средств доступа к аргументам в терминахGetCommandLine
функции API.Подводя итог, ничто не мешает вам добавлять
const
кargc
, но самый полезныйconst
-ness наargv
даст вам нестандартнуюmain
функцию, скорее всего , не признаются в качестве таковых. К счастью (по иронии судьбы), есть веская причина не использовать стандартныеmain
аргументы для переносимого серьезного кода. Проще говоря, для практических целей они поддерживают только старый ASCII, содержащий только буквы английского алфавита.источник
main
подпись работает нормально, и вы можете получать произвольные аргументы Unicode.Подпись
main
является своего рода историческим артефактом изC
. ИсторическиC
не былоconst
.Однако вы можете объявить свой параметр,
const
поскольку константа влияет только на время компиляции.источник
const
был добавлен в C89 / C90; до этого он не был частью C.Потому
argc
что это локальная переменная (а в C ++ не ссылка или что-то в этом роде), и потому, что особое местоmain
означает, что махинации с обратной совместимостью предоставляют ей огромную свободу действий без веских причин заставлять приложения делать ее константой.эти и многие другие варианты будут компилироваться на широком спектре компиляторов C и C ++.
Так что в конечном итоге дело не в том, что argc не является const, просто это не обязательно, но может быть, если вы хотите, чтобы это было.
http://ideone.com/FKldHF , пример C:
http://ideone.com/m1qc9c , пример C ++
источник
-std=c++11
. Clang также принимает это, но даетwarning: only one parameter on 'main' declaration [-Wmain]
, и MSVC протестует только по поводу отсутствия спецификатора возвращаемого типа и отсутствия ссылки на argc. Снова «махинации» и «Помимо исторических причин, хорошая причина оставить argc и argv non-
const
состоит в том, что реализация компилятора не знает, что вы собираетесь делать с аргументами для main, она просто знает, что она должна предоставить вам эти аргументы.Когда вы определяете свои собственные функции и связанные с ними прототипы, вы знаете, какие параметры вы можете создать,
const
а какие - ваша функция будет изменять.Взятый до крайности, вы могли бы заявить , что все параметры для всех функций должны быть объявлены
const
, а затем , если у вас есть причина , чтобы изменить их (например , уменьшение индекса для поиска через массив), то вы должны сделать местные Непро-const
переменным и скопируйтеconst
значения аргументов в эти переменные. Это создает напряженную работу и лишние LOC без реальной выгоды. Хороший статический анализатор подберет, если вы не изменяете значение аргумента, и порекомендует вам сделать параметрconst
.источник