int main( const int argc , const char[] const argv)
Comme l' article n ° 3 du C ++ efficace déclare "Utiliser const chaque fois que possible", je commence à penser "pourquoi ne pas rendre ces paramètres const
" constants "?.
Existe-t-il un scénario dans lequel la valeur de argc
est modifiée dans un programme?
argc
commeconst
.--argc
const
; en effet, passerargc
comme unconst int
moyen que vous ne pouvez pas utiliser ensuiteargc
comme un compteur à l'intérieur de la fonction.const
un paramètre passe-par-valeur. Voir par exemple stackoverflow.com/a/8714278/277304 et stackoverflow.com/a/117557/277304Réponses:
Dans ce cas, l'histoire est un facteur. C a défini ces entrées comme "non constantes", et la compatibilité avec (une bonne partie du) code C existant était l'un des premiers objectifs de C ++.
Certaines API UNIX, telles que
getopt
, manipulent réellementargv[]
, donc cela ne peut pas être faitconst
pour cette raison également.(A part: Fait intéressant, bien que
getopt
le prototype suggère qu'il ne modifiera pasargv[]
mais peut modifier les chaînes pointées, la page de manuel Linux indique quegetopt
permute ses arguments, et il semble qu'ils savent qu'ils sont vilains . La page de manuel à l'Open Group ne mentionne pas cette permutation.)La mise
const
surargc
etargv
ne serait pas acheter beaucoup, et il invaliderait certaines pratiques de programmation de la vieille école, tels que:J'ai écrit de tels programmes en C et je sais que je ne suis pas seul. J'ai copié l'exemple de quelque part .
la source
const
àargv
, sans affecter ce qu'une fonction C peut faire. En outre,getopt
est déclaré commeint getopt(int argc, char * const argv[], const char *optstring);
. Et ici, ceconst
n'est pas le niveau le plus élevé, mais déclare que les pointeurs sontconst
, une promesse de ne pas les modifier (bien que les chaînes sur lesquelles ils pointent pourraient éventuellement être modifiées).char* const* ___argv
là, mais l'interface adhère en faitconst char **
. Une telle confusion. J'avais confondu la préséance du[]
et du*
par rapport auconst
. Mes excuses.getopt()
sait qu'il ne suit pas la norme car il fait attention à laPOSIXLY_CORRECT
variable d'environnement pour qu'il se comporte correctement. En particulier, POSIX ne permute pas les arguments et ne recherche pas les options après le premier argument sans option.La norme C (ISO / CEI 9899: 2011) dit:
Notez le dernier point. Il dit que les deux
argc
etargv
devraient être modifiables. Ils ne doivent pas être modifiés, mais ils peuvent être modifiés.la source
QApplication(argc,argv)
constructeur de Qt était défini avecargc
par référence . Cela m'a surpris.argc
n'est normalement pas une constante car la signature de fonction pourmain()
les dates antérieuresconst
.Puisque argc est une variable de pile, sa modification n'affectera rien d'autre que votre propre traitement en ligne de commande.
Vous êtes bien entendu libre de le déclarer
const
si vous le souhaitez.la source
Un niveau supérieur
const
sur un argument formel ne fait pas partie du type de fonction. Vous pouvez l'ajouter ou le supprimer à votre guise: cela n'affecte que ce que vous pouvez faire avec l'argument dans l'implémentation de la fonction.Donc, pour
argc
vous pouvez ajouter librement ajouter un fichierconst
.Mais pour
argv
vous ne pouvez pas faire les données de caractèresconst
sans pour autant changer la signature de la fonction. Ce qui signifie qu'il ne s'agit alors pas de l'unemain
des signatures de fonction standard et qu'il n'aura pas à être reconnu comme unemain
fonction. Donc, ce n'est pas une bonne idée.Une bonne raison pour ne pas utiliser les
main
arguments standard dans les programmes non-jouets est que dans Windows, ils ne sont pas capables de représenter les arguments de programme réels tels que les noms de fichiers avec des caractères internationaux. C'est parce que dans Windows, ils sont codés par une convention très forte comme Windows ANSI. Dans Windows, vous pouvez implémenter une fonction d'accès aux arguments plus portable en termes deGetCommandLine
fonction API.En résumé, rien ne vous empêche d'ajouter
const
àargc
, mais l'utilité la plus utileconst
surargv
vous donnerait une fonction non standardmain
, très probablement non reconnue comme telle. Heureusement (d'une manière ironique) il y a de bonnes raisons de ne pas utiliser lesmain
arguments standards pour le code sérieux portable. Tout simplement, pour la pratique, ils ne prennent en charge que l'ancien ASCII, avec uniquement des lettres de l'alphabet anglais.la source
main
signature standard fonctionne bien et vous pouvez recevoir des arguments Unicode arbitraires.La signature de
main
est en quelque sorte un artefact historique deC
. HistoriquementC
n'a pas euconst
.Cependant, vous pouvez déclarer votre paramètre
const
car les effets de const sont uniquement à la compilation.la source
const
a été ajouté à C89 / C90; avant cela, il ne faisait pas partie de C.Parce que
argc
c'est une variable locale (et, en C ++, pas une référence ou quelque chose), et parce que la place spéciale demain
signifie que les manigances de compatibilité ascendante lui accordent une énorme marge de manœuvre sans raison impérieuse de forcer les applications à le rendre const.ces variantes et bien d'autres seront compilées sur une large gamme de compilateurs C et C ++.
Donc en fin de compte, ce n'est pas que argc ne soit pas const, mais que ce n'est pas nécessaire, mais cela peut l'être si vous le souhaitez.
http://ideone.com/FKldHF , exemple C:
http://ideone.com/m1qc9c , exemple C ++
la source
-std=c++11
. Clang l'accepte également mais donnewarning: only one parameter on 'main' declaration [-Wmain]
, et MSVC ne proteste que contre le spécificateur de type de retour manquant et l'absence de référence à argc. Encore une fois, 'shenanigans' et 'Mis à part les raisons historiques, une bonne raison de garder argc et argv non-
const
est que l'implémentation du compilateur ne sait pas ce que vous allez faire avec les arguments de main, elle sait juste qu'elle doit vous donner ces arguments.Lorsque vous définissez vos propres fonctions et les prototypes associés, vous savez quels paramètres vous pouvez créer
const
et ceux que votre fonction va modifier.Poussé à l'extrême, vous pouvez déclarer que tous les paramètres de toutes les fonctions doivent être déclarés
const
, puis si vous avez une raison de les modifier (par exemple, décrémentez un index pour rechercher dans un tableau), vous devrez créer des non-const
variables locales et copiez lesconst
valeurs des arguments dans ces variables. Cela permet un travail chargé et un LOC supplémentaire sans réel avantage. Un analyseur statique décent détectera si vous ne modifiez pas la valeur d'un argument et vous recommandera de créer le paramètreconst
.la source