Вот некоторые ссылки от MSDN Magazine на автоматическом коде тестирования:
Тот факт, что исходный язык C был таким, что по умолчанию любая переменная или аргумент определялась как тип int , вероятно, является другим фактором. Другими словами, у вас может быть:
main(argc, char* argv[]); /* see remark below... */
вместо
int main(int argc, char *argv[]);
Edit : эффективно, как напомнил нам Аарон, очень оригинальный синтаксис был бы чем-то вроде
main(argc, argv) char **argv {... }
, поскольку «прототипы» были представлены позже. Это произошло примерно после того, как каждый зарегистрировал минимум 10 часов в поисках тонких (и не очень тонких) ошибок, связанных с типами
Несколько причин:
unsigned
или целочисленных типов без знака int
, поскольку это было по умолчанию. int
тогда в некотором смысле был более важным. Все было инт. C частично произошел от языка, в котором даже не было типов. Каждая переменная представляла собой слово
, для чего изначально использовалась int
. ОБНОВЛЕНИЕ: Джейсон С. запросил источники. Развитие языка C . Возможно, вам придется найти более ранние языки BCPL и B в обычных местах.
Because C is old, and it was designed that way from the start. It's too late to change it now.
Here's a history of the C programming language in dmr's own words. It's not stated explicitly (at least not from the quick skim I gave it), but the earliest versions of C didn't support unsigned types. mjv's point about implicit typing to int
is also relevant.
EDIT
The Bell Labs link has been broken for a while: here's an alternate link to the same paper.
Другой причиной может быть то, что беззнаковые типы могут быть неудобны для итерации. Например, следующий фрагмент, повторяющийся вниз:
for (size_t i = SIZE - 1; i >= 0; --i)
...
, на самом деле, является ошибкой. Когда i достигает 0 на последней итерации, он переходит прямо в 4294967295 (на 32-битной машине), и цикл не завершается.
По этой причине я лично считаю, что простые целые числа более удобны для итерации. Не нужно быть особенно осторожным при переключении цикла для
с обратного счета на обратный при использовании целых чисел.
Руководство по стилю Google C ++ предлагает никогда не использовать типы unsigned int
, если вы не работаете с фактическими битовыми шаблонами. Их логика применима и к C. Строка краткого обзора:
... Схема продвижения типов в C заставляет беззнаковые типы вести себя иначе, чем можно было бы ожидать. ... Не используйте беззнаковый тип.
Вероятно, это не было в умах первоначального создателя C, но кто знает‽
It was a prescient design decision to make it easier to port C programs to Java in the future since there are no unsigned types in Java.
Я понимаю, как это может показаться странным: argc
не должно быть отрицательным! Но посмотрите на это так: и int
, и unsigned int
охватывают диапазон значений, которые вы бы приняли (если у вас есть 2 ^ 31 параметров командной строки, у вас есть проблема) и int
короче для ввода.
Вопрос-загадка для интервью: сколько клавиатур было бы израсходовано, набирая unsigned
, если бы C использовал unsigned int argc
?
При установке значения int диапазон ограничивается значением от 1 до INT_MAX включительно. Как правило, это означает, что никакое случайное приведение или псевдоним не выведет его из диапазона непреднамеренного переноса. Это также позволяет реализациям использовать весь отрицательный диапазон и диапазон 0.
Хорошо, я только что придумал. Настоящая причина в том, что это было просто произвольное решение, которое принял один из разработчиков исходного языка C, и до сих пор никто особо не задумывался об этом. :)
Простой вопрос: ожидаете ли вы более 2 31 (или даже более 2 15 ) аргументов командной строки? Я сомневаюсь, что большинство операционных систем сможет справиться с таким количеством.
I suppose it is designed to be compatible with C, and in C times people didn't really care that much about signed/unsigned correctness.
В качестве решения вашей проблемы с предупреждениями вы можете сделать что-то вроде этого, чтобы подавить предупреждения:
const unsigned int uargc = (unsigned int) argc;
Объявление для main ()
было определено до того, как беззнаковые типы были добавлены в язык - см. Страницу DMR на " Первобытный C ". Когда добавляли unsigned, было слишком поздно что-то менять.