Почему argc - это ' int '(а не 'unsigned int')?
Почему аргументы командной строки подсчитывают переменную (традиционно "argc") и 'int' вместо 'unsigned int'? Есть ли для этого техническая причина?
Я всегда просто игнорировал его при попытке избавиться от всех моих подписанных предупреждений о сравнении без знака, но никогда не понимал, почему это так.
13 ответов:
тот факт, что исходный язык C был таким, что по по умолчанию любая переменная или аргумент был определен как тип int, вероятно, еще один фактор. Другими словами, вы могли бы:
main(argc, char* argv[]); /* see remark below... */, а не
int main(int argc, char *argv[]);Edit: фактически, как напомнил нам Аарон, очень оригинальный синтаксис был бы чем-то вроде
main(argc, argv) char **argv {... }Так как "прототипы" были представлены только позже. Это произошло примерно после того, как все имели регистрируется минимум 10 часов погони за тонкими (и не очень тонкими) ошибками типа
несколько причин:
- потому что это не важно
- потому что C изначально не было
unsignedключевое слово целочисленные типы без знака- потому что C изначально не проверял типы параметров и даже не имел прототипов.
в результате, это была обычная практика, чтобы даже не объявлятьintтипы, как это было по умолчанию.- , потому что
intбыла, в некотором смысле, более важным тогда. Все было целое. C частично развился из языка, который даже не имел типов. Каждый вариабель былword, чтоintпервоначально использовался для.обновление:Джейсон S попросил источников. Я думаю, что вы можете выкопать все это (за исключением "это не имеет значения") из бумаги dmr, который находится на линии: развитие языка C. Возможно, вам придется искать более ранние языки BCPL и B в обычном режиме места.
потому что C старый, и он был разработан таким образом с самого начала. Сейчас уже слишком поздно что-то менять.
здесь история языка программирования C в собственных словах dmr. Это не указано явно (по крайней мере, не из быстрого скима, который я дал ему), но самые ранние версии C не поддерживали беззнаковые типы. точка mjv о неявном вводе в
intтакже имеет значение.EDIT
ссылка Bell Labs была прервана на некоторое время:здесь альтернативная ссылка на тот же документ.
другая причина может заключаться в том, что неподписанные типы могут быть неудобными для итерации. Например, этот фрагмент итерации вниз:
for (size_t i = SIZE - 1; i >= 0; --i) ...- это, по сути, ошибка. Когда я достигну 0 в последней итерации, он перейдет прямо в 4294967295 (на 32-разрядной машине), и цикл не завершится.
по этой причине я лично нахожу простые ints более удобными для итерации. Вы не должны быть особенно осторожны, когда вы переключаете
forцикл от подсчета до обратный отсчет при использовании ints.
на Руководство По Стилю Google C++ предполагает не использовать
unsigned intтипы, если вы не работаете с фактическими битовыми шаблонами. Их обоснование применимо и к C. Краткая строка резюме:... Схема продвижения типа C приводит к тому, что неподписанные типы ведут себя иначе, чем можно было бы ожидать. ... Не используйте тип без знака.
Это, вероятно, не было в сознании первоначального создателя C, но кто знает‽
в качестве решения проблемы предупреждения, вы можете сделать что-то вроде этого, чтобы подавить предупреждения:
const unsigned int uargc = (unsigned int) argc;
Это было предвиденное дизайнерское решение, чтобы облегчить перенос программ C на Java в будущем, так как в Java нет беззнаковых типов.
объявление
main()был определен до добавления беззнаковых типов в язык-см. страницу DMR на 'Первобытный C'. Это было слишком поздно, чтобы изменить, когда без подписи был добавлен.
Я вижу, как это может показаться странным:
argcне должно быть отрицательным! Но взгляните на это так: обаintиunsigned intохватите диапазон значений, которые вы приняли бы (если у вас есть 2^31 параметров командной строки, у вас есть проблема) иintкороче типа.интервью головоломка вопрос: сколько клавиатур было бы использовано до ввода
unsignedесли бы C пошел сunsigned int argc?
установив его в int, диапазон ограничивается от 1 до INT_MAX включительно. Это, как правило, означает, что никакое случайное приведение или псевдоним не выведет его из диапазона от непреднамеренного обертывания. Это также позволяет реализациям использовать весь отрицательный и нулевой диапазон для системных сценариев.
хорошо, я только что это придумал. Настоящая причина заключается в том, что это было просто произвольное решение, которое сделал один из разработчиков оригинального языка C, и никто действительно не думал, что это сложно об этом до сих пор. :)
простой вопрос: вы ожидаете больше, чем 231 (или даже больше, чем 215) аргументы командной строки? Я сомневаюсь, что большинство операционных систем может справиться с таким количеством.
Я полагаю, что он разработан, чтобы быть совместимым с C, и в C раз люди действительно не заботились о подписанной/неподписанной корректности.
Comments