2013-06-30 6 views
-2

Le compilateur donne l'avertissement warning: second argument of ‘int main(int, std::string*)’ should be ‘char **’ [-Wmain] principal() std :: string au lieu de char ** pourquoi l'exclusion

lorsque je choisis de mettre en

int main(int argv, std::string a[])

au lieu de

int main(int argv, char * argc [])

Si vous pouvez trouver une raison, priez également dotell ce qui ne va pas l'approche de la chaîne. Je veux dire avec std :: string étant l'enfant de la représentation des caractères/de la chaîne de caractères, pour C++, pourquoi s'embêter avec les styles C?

AUSSI

Est-il vraiment pas pirater autour de la mise en œuvre standard?

+8

Parce que 'main()' n'est pas autorisé à avoir un paramètre 'std :: string' dans le code conforme aux normes. Voir [ici] (http://en.wikipedia.org/wiki/Main_function). – juanchopanza

+9

Alerte spoiler: Les noms "argv" et "argc" signifient en fait * quelque chose, et il y a une raison pour laquelle ils sont habituellement utilisés dans un ordre spécifique. –

+1

"Y at-il une raison pour laquelle le compilateur donne l'avertissement" - Eh bien, qu'en pensez-vous? Le compilateur émet des avertissements juste pour le plaisir, sans aucune raison, juste pour vous ennuyer? (vous le méritez, mais quand même ...) –

Répondre

10

La raison est assez simple: les règles de langage ne mandatent pas votre formulaire et l'implémentation que vous utilisez ne le supporte pas de son propre choix.

Citant la norme 3.6.1p2

Une mise en œuvre ne doit pas prédéfinir la fonction principale. Cette fonction ne doit pas être surchargée. Il doit avoir un type de retour de type int, mais sinon son type est défini par l'implémentation. Toutes les mises en œuvre devrait permettre aux deux des définitions suivantes des principaux:

int main() { /* ... */ } 

et

int main(int argc, char* argv[]) { /* ... */ } 

Dans cette dernière forme argc est le nombre d'arguments passés au programme de l'environnement dans lequel le programme est exécuté. Si argc est différent de zéro, ces arguments doivent être fournis dans argv [0] par argv [argc-1] comme pointeurs sur les caractères initiaux des chaînes multi-octets à terminaison nulle (NTMBS) (17.3.2.1.3.2) et argv [0] doit être le pointeur vers le caractère initial d'un NTMBS qui représente le nom utilisé pour appeler le programme ou "". La valeur de argc doit être non négative. La valeur de argv [argc] doit être 0. [Remarque: il est recommandé d'ajouter d'autres paramètres (facultatifs) après argv. ]

EDIT: pour couvrir la question supplémentaire:

Il n'y a pas besoin de « pirater » quoi que ce soit, que rien n'empêche d'utiliser une fonction ou une classe qui prend la argc et argv d'origine et traite à un vecteur littéralement, ou mieux encore analyser et cartographier les données traitées en variables internes. Nous avons beaucoup de ceux qui flottent autour, et ceux qui créent plus d'une poignée de main (s) par an utilisent probablement déjà l'un de ceux-ci ou le leur.

+0

Bien mis.Pour quelle raison il est implémenté en tant que tel? Je veux dire que si std :: string est disponible et est le posterchild C++ pour la représentation de chaîne, pourquoi s'embêter avec char? –

+7

Raisins hystériques. – aschepler

+0

Raisons historiques? –

8

Solution:

vector<string> args(argv, argv + argc); 

for (auto s: args) 
     cout << s << endl; 

std::string et std::vector sont des objets de poids lourds. L'allocation dynamique de la mémoire est utilisée lors de leur construction.

La deuxième façon de le faire est d'utiliser my RO library. Ci-dessous le code va créer un poids léger gamme iterator objet autour argv tableau:

auto args = ro::range(argv,argv+argc); 

for (auto s: args) 
     cout << s << endl; 
+5

Je lui donnerais +1 s'il n'avait pas l'abominable 'namespace abusant std;'. –

+2

Enseigner aux mauvaises recrues est encore pire! Ils n'ont pas le pouvoir mental de voir à travers les mauvaises parties de votre conseil :-( –

+0

@LeonidVolnitsky Ce n'est pas une excuse, en fait, KerrekSB a raison et encourager les nouveaux arrivants à utiliser de mauvaises pratiques est une grave erreur. –

1

Vous avez donné la raison pour laquelle votre mise en œuvre besoin pas le soutenir. Cependant, il y a aussi une raison pour laquelle votre mise en œuvre ne veulent pour le soutenir:

Le (habituellement précompilés) code d'appel main passe un int et un char** (et dans certaines mises en œuvre que l'extension d'une seconde char**, en effet, sur un grand nombre plates-formes, il obtient exactement les données déjà fournies par le système d'exploitation et le transmet simplement). Il est facile de supporter d'ignorer les arguments finaux (généralement, ils sont poussés vers la pile dans l'ordre inverse, donc ignorer les arguments supplémentaires signifie simplement ne pas y accéder, aucune logique supplémentaire n'est nécessaire). Cependant, vous ne pouvez pas lire un char** comme std::string*, par conséquent le compilateur devrait générer du code supplémentaire pour supporter cette interface. Étant donné que tout code source utilisant cette interface serait de toute façon non portable et que peu de personnes l'utiliseraient, et que l'interface originale fonctionnait correctement, ce serait un gaspillage de ressources pour implémenter cette interface alternative.

Questions connexes