Почему 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 раз люди не очень заботились о правильности подписанных/неподписанных.