int main( const int argc , const char[] const argv)
Como el artículo n. ° 3 de C ++ efectivo dice "Use const siempre que sea posible", empiezo a pensar "¿por qué no hacer estos parámetros 'constantes' const"?
¿Existe algún escenario en el que argcse modifique el valor de en un programa?

argccomoconst.--argcconst; de hecho, pasarargccomo unconst intmedio que luego no puede usarargccomo, digamos, un contador dentro de la función.constun parámetro de paso por valor. Ver, por ejemplo, stackoverflow.com/a/8714278/277304 y stackoverflow.com/a/117557/277304Respuestas:
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 uno de los primeros objetivos de C ++.
Algunas API de UNIX, como
getopt, en realidad manipulanargv[], por lo que no se pueden crear tambiénconstpor esa razón.(Aparte: Curiosamente, aunque
getoptel prototipo sugiere que no modificaráargv[]pero puede modificar las cadenas señaladas, la página de manual de Linux indica quegetoptpermuta sus argumentos, y parece que saben que están siendo traviesos . La página de manual de Open Group no menciona esta permutación).Poniendo
constenargcyargvno comprar mucho, y sería invalidar algunos de la vieja escuela prácticas de programación, tales como:He escrito este tipo de programas en C y sé que no estoy solo. Copié el ejemplo de alguna parte .
fuente
constaargv, sin afectar lo que puede hacer cualquier función C. Además,getoptse declara comoint getopt(int argc, char * const argv[], const char *optstring);. Y aquíconstno es el nivel superior, pero declara que los punteros sonconst, una promesa de no modificarlos (aunque las cadenas a las que apuntan posiblemente se modifiquen).getoptpermuta laargv[]matriz por defecto, pero no modifica las cadenas. (La palabra permute viene directamente de la página del manual). Eso significa que laargvmatriz en sí no esconstincluso si las cadenas a las que apunta lo son. ¿Cómo permutar laargv[]matriz no manipularla?char* const* ___argvahí, pero la interfaz realmente se adhiereconst char **. Tanta confusión. Había confundido la precedencia de the[]y the*con respecto a theconst. Mis disculpas.El estándar C (ISO / IEC 9899: 2011) dice:
Tenga en cuenta la última viñeta. Dice que ambos
argcyargvdeberían ser modificables. No es necesario modificarlos, pero pueden modificarse.fuente
QApplication(argc,argv)constructor de Qt se definió conargcpor referencia . Eso me sorprendió.argcnormalmente no es una constante porque la firma de función paramain()fechas anterioresconst.Dado que argc es una variable de pila, cambiarla no afectará a nada más que a su propio procesamiento de línea de comando.
Por supuesto,
consteres libre de declararlo si quieres.fuente
Un nivel superior
consten 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
argcque pueda agregar libremente, agregue un archivoconst.Pero
argvno se pueden hacer los datos del carácterconstsin cambiar la firma de la función. Lo que significa que entonces no es una de lasmainfirmas de función estándar y no tendrá que ser reconocida como unamainfunción. Entonces, no es una buena idea.Una buena razón para no usar los
mainargumentos estándar en 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 están codificados por convención muy fuerte como Windows ANSI. En Windows, puede implementar algunasGetCommandLinefunciones de acceso a argumentos más portátiles en términos de la función API.En resumen, nada impide que se agreguen
constaargc, pero el más útilconst-ness enargvque le daría un no-estándar demainla función, la mayoría probablemente no reconocido como tal. Afortunadamente (de manera irónica) hay buenas razones para no usar losmainargumentos estándar para código serio portátil. En pocas palabras, para la práctica solo admiten el antiguo ASCII, con solo letras del alfabeto inglés.fuente
mainfirma estándar funciona bien y usted puede recibir argumentos Unicode arbitrarios.La firma de
maines algo así como un artefacto histórico deC. HistóricamenteCno lo teníaconst.Sin embargo, puede declarar su parámetro
constya que los efectos de const son solo en tiempo de compilación.fuente
constse añadió a C89 / C90; antes de eso, no era parte de C.Porque
argces una variable local (y, en C ++, no una referencia o algo así), y porque el lugar especial demainsignifica que los chanchullos de compatibilidad con versiones anteriores le otorgan una gran cantidad de libertad sin ninguna razón convincente para forzar a las aplicaciones a hacerla constante.estas y muchas otras variaciones se compilarán en una amplia gama de compiladores C y C ++.
Entonces, en última instancia, no es que argc no sea constante, solo que no tiene que serlo, pero puede serlo si quieres que lo sea.
http://ideone.com/FKldHF , ejemplo de C:
http://ideone.com/m1qc9c , ejemplo de C ++
fuente
-std=c++11. Clang también lo acepta pero cedewarning: only one parameter on 'main' declaration [-Wmain], y MSVC solo protesta por el especificador de tipo de retorno que falta y la falta de una referencia a argc. Nuevamente, 'travesuras' y 'libertad deAparte de las razones históricas, una buena razón para mantener argc y argv non-
constes que la implementación del compilador no sabe qué vas a hacer con los argumentos de main, solo sabe que debe darte esos argumentos.Cuando está definiendo sus propias funciones y prototipos asociados, sabe qué parámetros puede hacer
consty cuáles modificará su función.Llevado al extremo, podría declarar que todos los parámetros de todas las funciones deben declararse
const, y luego, si tuviera una razón para cambiarlos (por ejemplo, disminuir un índice para buscar en una matriz), tendría que hacer que no seanconstvariables locales y copie losconstvalores de los argumentos en esas variables. Eso lo convierte en un trabajo ajetreado y un LOC adicional sin ningún beneficio real. Un analizador estático decente se activará si no está modificando el valor de un argumento y le recomendará que cree el parámetroconst.fuente