¿Por qué argc no es una constante?
int main( const int argc , const char[] const argv)
Como C++efectivo El artículo#3 establece "Usar 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?
7 answers
En este caso, la historia es un factor. C definió estas entradas como" no constantes", y la compatibilidad con (una buena parte) del código C existente fue un objetivo temprano de C++.
Algunas API de UNIX, como getopt
, en realidad manipulan argv[]
, por lo que no se puede hacer const
por esa razón también.
(Aparte: Curiosamente, aunque el prototipo de getopt
sugiere que no modificará argv[]
sino que 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 de manual del Grupo Abierto 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 tales programas en C, y sé que no estoy solo. Copié el ejemplo de en algún lugar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 04:55:09
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 aplicación declara no prototipo para esta función. Se definirá con un tipo de retorno de int y con no parámetros:int main(void) { /* ... */ }
O con dos parámetros (referidos aquí como
argc
yargv
, aunque cualquier nombre puede ser se utilizan, ya que son locales a la función en la que se declared):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 lo siguiente limitaciones:
- El valor de
argc
no será negativo.argv[argc]
será un puntero nulo.- Si el valor de
argc
es mayor que cero, los miembros de la matrizargv[0]
a través deargv[argc-1]
inclusive contendrá punteros a cadenas, que son dar valores definidos por el entorno host antes del inicio del programa. El la intención es proporcionar al programa información determinada antes del inicio del programa desde cualquier otro lugar del entorno alojado. Si el entorno host no es capaz de el suministro de 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 en el entorno host. Si el valor deargc
es mayor que uno, las cadenas apuntadas porargv[1]
hastaargv[argc-1]
representar los parámetros del programa.- Los parámetros
argc
yargv
y las cadenas apuntadas por la matrizargv
deberán ser modificables por el programa, y conservar sus últimos valores almacenados entre el programa inicio y terminación del programa.10) Así,
int
puede ser reemplazado por un nombre typedef definido comoint
, o el tipo deargv
puede ser escrito comochar **argv
, y así sucesivamente.
Nótese el último punto. Dice que tanto argc
como argv
deben ser modificables. No tienen que ser modificados, pero pueden ser modificados.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 03:25:19
argc
normalmente no es una constante porque la firma de función para main()
es anterior a const
.
Dado que argc es una variable de pila, cambiarla no afectará a nada más que su propio procesamiento de línea de comandos.
Usted es, por supuesto, libre de declararlo const
si lo desea.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 03:19:30
Un nivel superior const
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.
Así que para argc
puede agregar libremente agregar un const
.
Pero para argv
no puede hacer que los datos de caracteres const
sin cambiar la firma de la función. Lo que significa que entonces no es una de las firmas de función estándar main
, y no tendrá que ser reconocida como una main
función. Así que no es una buena idea.
Una buena razón para no usar los argumentos estándar main
en programas que no son de juguete es que en Windows no son capaces de representar argumentos de programa reales como nombres de archivo con caracteres internacionales. Eso es porque en Windows son por convención muy fuerte codificado como ANSI de Windows. En Windows puede implementar alguna facilidad de acceso a argumentos más portátil en términos de la función API GetCommandLine
.
Resumiendo, nada le impide agregar const
a argc
, pero la función const
más útil en argv
le daría una función main
no estándar, probablemente no reconocida como tal. Felizmente (de una manera irónica) hay buenas razones para no usar los argumentos estándar main
para portable serious code. Simplemente, para la práctica solo admiten ASCII antiguo, con solo letras del alfabeto inglés.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 04:23:31
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 en tiempo de compilación.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 03:13:42
Porque argc
es una variable local (y, en C++, no una referencia o algo así), y porque el lugar especial de main
significa que las travesuras de compatibilidad hacia atrás le otorgan una gran cantidad de margen de maniobra sin ninguna razón convincente para forzar aplicaciones para que sea constante.
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 se compilarán en una amplia gama de compiladores de C y C++.
Así que en última instancia, no es que argc no sea const, solo que no tiene que serlo, pero puede serlo si quiero que lo sea.
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) {}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 05:50:43
Aparte de las razones históricas, una buena razón para mantener argc y argv no-const
es que la implementación del compilador no sabe lo que va a hacer con los argumentos de main, solo sabe que debe darle esos argumentos.
Cuando está definiendo sus propias funciones y prototipos asociados, sabe qué parámetros puede hacer const
y cuáles modificará su función.
Llevado a un extremo, podría declarar que todos los parámetros de todas las funciones debería declararse const
, y luego si tuviera una razón para cambiarlas (por ejemplo, decrementar un índice para buscar a través de un array), tendría que hacer variables locales no-const
y copiar los valores de los argumentos const
en esas variables. Eso lo convierte en trabajo ocupado y LOC adicional sin ningún beneficio real. Un analizador estático decente captará si no está modificando el valor de un argumento, y le recomendará que cree el parámetro const
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 19:32:27