c++ - sirve - que es main en programacion
¿Por qué argc no es una constante? (7)
Además de las razones históricas, una buena razón para mantener a argc y argv non- const
es que la implementación del compilador no sabe qué vas a hacer con los argumentos para main, simplemente sabe que debe darte esos argumentos.
Cuando defina sus propias funciones y prototipos asociados, sabrá qué parámetros puede hacer const
y cuáles modificará su función.
Llevado al extremo, podría declarar que todos los parámetros de todas las funciones deberían declararse const
, y luego, si tenía una razón para cambiarlos (por ejemplo, disminuir un índice para buscar a través de una matriz), tendría que hacer local non- const
variables y copia los valores de los argumentos de const
en esas variables. Eso hace que el trabajo ocupado y el LOC adicional no tengan ningún beneficio real. Un analizador estático decente se activará si no está modificando el valor de un argumento, y le recomendará que establezca el parámetro const
.
int main( const int argc , const char[] const argv)
Como el Artículo # 3 efectivo de C ++ dice "Use const siempre que sea posible", empiezo a pensar "¿por qué no hacer estos parámetros ''constantes'' const
"?
¿Hay algún escenario en el que el valor de argc
se modifique en un programa?
Debido a que argc
es una variable local (y, en C ++, no es una referencia o algo), y porque el lugar especial de main
significa que las trabas de compatibilidad hacia atrás le otorgan una gran cantidad de margen sin una razón convincente para forzar aplicaciones que lo hagan const.
main() {}
int main() {}
main() { return 0; }
main(int argc, char* argv[]) { return 0; }
int main(const int argc, const char** argv) { /* no return*/ }
estas y muchas otras variaciones compilarán en una amplia gama de compiladores C y C ++.
Así que, en última instancia, no es que argc no sea const, solo que no tiene que ser así, pero puede ser si así lo quieres.
http://ideone.com/FKldHF , C ejemplo:
main(const int argc, const char* argv[]) { return 0; }
http://ideone.com/m1qc9c , ejemplo de C ++
main(const int argc) {}
El estándar C (ISO / IEC 9899: 2011) dice:
5.1.2.2.1 Inicio del programa
¶1 La función llamada al inicio del programa se llama
main
. La implementación no declara ningún prototipo para esta función. Se definirá con un tipo de retorno de int y sin parámetros:
int main(void) { /* ... */ }
o con dos parámetros (a los que se hace referencia aquí como
argc
yargv
, aunque se pueden usar los nombres, ya que son locales para la función en la que se declaran):
int main(int argc, char *argv[]) { /* ... */ }
o equivalente; 10) o de alguna otra manera definida por la implementación.
¶2 Si se declaran, los parámetros de la función
main
obedecerán las siguientes restricciones:
- El valor de
argc
debe ser no negativo.argv[argc]
será un puntero nulo.- Si el valor de
argc
es mayor que cero, los miembros de la matrizargv[0]
aargv[argc-1]
inclusive contendrán punteros a las cadenas, que reciben los valores definidos por la implementación por el entorno de host antes del inicio del programa. La intención es suministrar a la información del programa determinada antes del inicio del programa desde otro lugar en el entorno alojado. Si el entorno de host no es capaz de suministrar cadenas con letras en mayúsculas y minúsculas, la implementación se asegurará de que las cadenas se reciban en minúsculas.- Si el valor de
argc
es mayor que cero, la cadena apuntada porargv[0]
representa el nombre del programa;argv[0][0]
será el carácter nulo si el nombre del programa no está disponible desde el entorno host. Si el valor deargc
es mayor que uno, las cadenas apuntadas porargv[1]
aargv[argc-1]
representan los parámetros del programa.- Los parámetros
argc
yargv
y las cadenas apuntadas por la matrizargv
serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.10) Por lo tanto,
int
puede ser reemplazado por un nombre typedef definido comoint
, o el tipo deargv
puede escribirse comochar **argv
, y así sucesivamente.
Tenga en cuenta el último punto de viñeta. Dice que tanto argc
como argv
deben ser modificables. No tienen que ser modificados, pero pueden ser modificados.
En este caso, la historia es un factor. C definió estas entradas como "no constantes", y la compatibilidad con (una buena porción de) el código C existente fue un objetivo temprano de C ++.
Algunas API de UNIX, como getopt
, realmente manipulan argv[]
, por lo que no pueden const
por esa razón también.
(Aparte: Curiosamente, aunque el prototipo de getopt
sugiere que no modificará argv[]
pero puede modificar las cadenas apuntadas, la página man de Linux indica que getopt
permuta sus argumentos, y parece que saben que están siendo traviesos . la página man en Open Group no menciona esta permutación).
Poner const
en argc
y argv
no compraría mucho, e invalidaría algunas prácticas de programación de la vieja escuela, tales como:
// print out all the arguments:
while (--argc)
std::cout << *++argv << std::endl;
He escrito dichos programas en C, y sé que no estoy solo. Copié el ejemplo de alguna parte .
La firma de main
es algo así como un artefacto histórico de C
Históricamente C
no tenía const
.
Sin embargo, puede declarar su parámetro const
ya que los efectos de const son solo tiempo de compilación.
Un const
nivel superior en un argumento formal no es parte del tipo de función. Puede agregarlo o eliminarlo como desee: solo afecta lo que puede hacer con el argumento en la implementación de la función.
Entonces para argc
puedes agregar libremente agregar un const
.
Pero para argv
no puede hacer const
datos de los caracteres sin cambiar la firma de la función. Lo que significa que no es una de las firmas de funciones main
estándar, y no tendrá que ser reconocida como una función main
. Entonces, no es una buena idea.
Una buena razón para no utilizar los argumentos main
estándar en los programas que no son de juguete es que en Windows no pueden representar los argumentos reales del programa, como los nombres de archivo con caracteres internacionales. Eso es porque en Windows son convenciones muy fuertes codificadas como Windows ANSI. En Windows puede implementar un GetCommandLine
acceso a argumentos más portátil en términos de la función GetCommandLine
API.
En resumen, nada le impide agregar const
a argc
, pero la const
-ness más útil en argv
le daría una función main
no estándar, muy probablemente no reconocida como tal. Afortunadamente (de manera irónica) hay buenas razones para no usar los argumentos main
estándar para el código portátil serio. Simplemente, para la práctica, solo admiten ASCII antiguo, con solo letras del alfabeto inglés.
argc
no es normalmente una constante porque la firma de la función para main()
anterior a la const
.
Como argc es una variable de pila, su cambio no afectará a nada más que a su propio procesamiento de línea de comando.
Usted es, por supuesto, libre de declararlo const
si lo desea.