Почему argc является "int" (а не "unsigned int" )?
Почему аргументы командной строки подсчитывают переменную (традиционно "argc" ) "int" вместо "unsigned int"? Есть ли техническая причина для этого?
Я всегда просто игнорировал это, пытаясь избавиться от всех моих подписанных предупреждений сравнения без знака, но никогда не понимал, почему так оно и есть.
Ответы
Ответ 1
Тот факт, что исходный язык C был таким, что по default любая переменная или аргумент была определена как тип int, вероятно, является еще одним фактором. Другими словами, вы могли бы:
main(argc, char* argv[]); /* see remark below... */
а не
int main(int argc, char *argv[]);
Изменить: эффективно, как напомнил нам Аарон, очень оригинальный синтаксис был бы чем-то вроде
main(argc, argv) char **argv {... }
Так как "прототипы" были введены позже. Это произошло примерно после того, как каждый зарегистрировал минимум как минимум 10 часов, преследуя тонкие (и не очень тонкие) ошибки, связанные с типом
Ответ 2
Несколько причин:
- потому что это не имеет значения.
- потому что у C первоначально не было ключевого слова
unsigned
или целых чисел без знака
- потому что C первоначально не проверял типы параметров и даже не имел прототипов. В результате обычной практикой было даже не объявлять типы
int
, поскольку это было по умолчанию.
- потому что
int
был в некотором смысле более важным тогда. Все было инт. C частично развился с языка, который даже не имел типов. Каждая отдельная переменная была word
, для чего первоначально использовался int
.
UPDATE: Джейсон С. попросил источники. Я думаю, что вы можете выкопать все это (за исключением "это не имеет значения" ) из статьи dmr, которая находится в режиме онлайн:
Разработка языка C. Возможно, вам придется искать более ранние языки BCPL и B в обычных местах.
Ответ 3
Потому что C старый, и он был разработан таким образом с самого начала. Слишком поздно менять его сейчас.
Ответ 4
Вот история языка программирования C в собственных словах dmr. Он не был указан явно (по крайней мере, не из того, что я дал ему), но самые ранние версии C не поддерживали неподписанные типы. Точка mjv о неявной типизации на int
также имеет значение.
ИЗМЕНИТЬ
Ссылка Bell Labs была нарушена на некоторое время: здесь альтернативная ссылка на ту же самую бумагу.
Ответ 5
Другая причина может заключаться в том, что неподписанные типы могут быть неудобными для итерации. Например, этот фрагмент итерации вниз:
for (size_t i = SIZE - 1; i >= 0; --i)
...
Является, по сути, ошибкой. Когда я достигнет 0 в последней итерации, он будет идти прямо на 4294967295 (на 32-битной машине), и цикл не завершится.
По этой причине я лично нахожу простые ints более удобными для итерации. Вам не обязательно быть особенно осторожным при переключении цикла for
от подсчета до подсчета при использовании int.
Ответ 6
Руководство по стилю Google С++ предлагает никогда не использовать типы unsigned int
, если вы не работаете с фактическими битовыми шаблонами. Их обоснование относится и к C. Краткая сводная строка:
... C-схема продвижения по типам приводит к тому, что неподписанные типы ведут себя иначе, чем можно было бы ожидать.... Не используйте неподписанный тип.
Это, вероятно, не было в умах оригинального автора C, но кто знает,
Ответ 7
Как решение проблемы с предупреждением, вы можете сделать что-то подобное, чтобы подавить предупреждения:
const unsigned int uargc = (unsigned int) argc;
Ответ 8
Это было предварительное дизайнерское решение, чтобы упростить перенос программ на C в Java в будущем, поскольку в Java нет беззнаковых типов.
Ответ 9
Объявление для main()
было определено до того, как к языку были добавлены неподписанные типы - см. страницу DMR на странице Первоначальный C. Слишком поздно менять, когда был добавлен unsigned.
Ответ 10
Я вижу, как это может показаться странным: argc
не должно быть отрицательным! Но посмотрите на это следующим образом: оба int
и unsigned int
охватывают диапазон значений, которые вы принимаете (если у вас есть параметры командной строки 2 ^ 31, у вас есть проблема), а int
короче для ввода.
Задайте вопрос о головоломке: сколько клавиатур было бы использовано, набрав unsigned
, если C ушел с unsigned int argc
?
Ответ 11
Установив его в int, диапазон ограничивается между 1 и INT_MAX включительно. Это, как правило, означает, что никакие случайные литые или псевдонимы не будут выходить за пределы от непреднамеренного обертывания. Он также позволяет реализациям использовать весь негатив и диапазон 0 для сценариев, специфичных для системы.
Хорошо, я только что сделал это. Настоящая причина заключается в том, что это было просто произвольное решение, сделанное одним из разработчиков языка C, и до сих пор никто не думал об этом.:)
Ответ 12
Простой вопрос: ожидаете ли вы более двух аргументов командной строки 31 (или даже более 2 15)? Я сомневаюсь, что большинство операционных систем могут справиться с этим.
Ответ 13
Я предполагаю, что он разработан, чтобы быть совместимым с C, и в C раз люди не очень заботились о правильности подписанных/неподписанных.