c++ - tipos - ¿Por qué argc es un ''int''(en lugar de un ''unsigned int'')?
unsigned int para que sirve (13)
¿Por qué los argumentos de la línea de comando cuentan la variable (tradicionalmente "argc") como ''int'' en lugar de ''int sin signo''? ¿Hay alguna razón técnica para esto?
Siempre lo he ignorado al intentar deshacerme de todas mis advertencias de comparación sin firmar firmadas, pero nunca he entendido por qué es así.
Al configurarlo en int, el rango se limita a entre 1 e INT_MAX inclusive. Esto normalmente significará que ningún lanzamiento o alias accidental lo sacará de un rango involuntario. También permite que las implementaciones utilicen todo el rango negativo y 0 para escenarios específicos del sistema.
Ok, acabo de hacer eso. La verdadera razón es que fue solo una decisión arbitraria que uno de los desarrolladores del lenguaje C original tomó, y nadie realmente lo pensó tan seriamente hasta ahora. :)
Algunas razones:
- porque no importa
- porque C no tenía originalmente la palabra clave sin signo o los tipos enteros sin signo
- porque C originalmente no verificó los tipos de parámetros y ni siquiera tenía prototipos.
Como resultado, era una práctica común no declarar tiposint
, ya que este era el valor predeterminado. - porque
int
era, en cierto sentido, más importante en aquel entonces. Todo fue un int. C evolucionó en parte desde un lenguaje que ni siquiera tenía tipos. Cada variable individual era unaword
, que es para lo que originalmente se usabaint
.
ACTUALIZACIÓN: Jason S pidió fuentes. Creo que puede extraer todo esto (a excepción de "no importa") de un documento de dmr que está en línea: El desarrollo del lenguaje C. Es posible que deba buscar los idiomas anteriores BCPL y B en los lugares habituales.
Como solución a su problema de advertencia, podría hacer algo como esto para suprimir las advertencias:
const unsigned int uargc = (unsigned int) argc;
El hecho de que el lenguaje C original fuera tal que, de forma predeterminada, cualquier variable o argumento se definió como tipo int , es probablemente otro factor. En otras palabras, usted podría tener:
main(argc, char* argv[]); /* see remark below... */
más bien que
int main(int argc, char *argv[]);
Edición : efectivamente, como Aaron nos recordó, la sintaxis muy original hubiera sido algo así como
main(argc, argv) char **argv {... }
Dado que los "prototipos" fueron introducidos más tarde. Eso ocurrió aproximadamente después de que todos hubieran registrado un mínimo de al menos 10 horas persiguiendo errores sutiles (y no tan sutiles) relacionados con el tipo
Fue una decisión de diseño anticipada que facilitara el transporte de los programas C a Java en el futuro, ya que no hay tipos sin firmar en Java.
La Guía de estilo de Google C ++ sugiere nunca usar tipos unsigned int
menos que esté trabajando con patrones de bits reales. Su razonamiento se aplica a C también. Línea de resumen rápido:
... el esquema de promoción de tipo de C hace que los tipos sin firma se comporten de manera diferente de lo que uno podría esperar. ... No utilice un tipo sin firmar.
Probablemente esto no estaba en la mente del creador original de C, pero quién sabe ...
La declaración para main()
se definió antes de agregar los tipos sin firmar al idioma; consulte la página de DMR en '' Primeval C ''. Era demasiado tarde para cambiar cuando se agregó unsigned.
Otra razón podría ser que los tipos sin firma pueden ser inconvenientes para la iteración. Por ejemplo, este fragmento de código iterando hacia abajo:
for (size_t i = SIZE - 1; i >= 0; --i)
...
Es, de hecho, un error. Cuando llegue a 0 en la última iteración, irá a la derecha a 4294967295 (en una máquina de 32 bits) y el bucle no terminará.
Por esta razón, personalmente me parece más conveniente para la iteración las intenciones simples. No tiene que ser especialmente cuidadoso cuando cambia un bucle for
de contar hacia arriba a contar hacia abajo al usar ints.
Porque C es viejo, y fue diseñado de esa manera desde el principio. Es demasiado tarde para cambiarlo ahora.
Solo una pregunta simple: ¿Espera más de 2 31 (o incluso más de 2 15 ) argumentos de línea de comando? Dudo que la mayoría de los sistemas operativos puedan manejar eso.
Supongo que está diseñado para ser compatible con C, y en C veces a las personas realmente no les importaba mucho la corrección firmada / no firmada.
Veo cómo puede parecer extraño: ¡ argc
no debería ser negativo! Pero véalo de esta manera: int
y unsigned int
cubren el rango de valores que aceptaría (si tiene 2 ^ 31 parámetros de línea de comando, tiene un problema) y int
es más corto de escribir.
Pregunta de la entrevista: ¿cuántos teclados se habrían utilizado al escribir el unsigned
si C se hubiera ido con unsigned int argc
?
Aquí hay una historia del lenguaje de programación C en las propias palabras de dmr. No se indica explícitamente (al menos no desde el contenido rápido que le di), pero las versiones más antiguas de C no admitían tipos sin firma. El punto de mjv sobre la escritura implícita en int
también es relevante.
EDITAR
El enlace de Bell Labs se ha roto por un tiempo: here''s un enlace alternativo al mismo documento.