J'ai actuellement un projet qui utilise g ++ pour compiler son code. Je suis en train de nettoyer le code et j'aimerais vous assurer que toutes les fonctions ont des prototypes, afin de garantir que les choses comme Cons-Char * sont correctement traitées. Malheureusement, g ++ se plaint lorsque j'essaie de spécifier -wmissing-prototypes: peut me dire: Voici un exemple de coupe et de pâte: p>
1) Pourquoi GCC n'est-il pas valide? Est-ce un bogue dans GCC?
2) Existe-t-il un moyen d'activer cet avertissement? P> cat > foo.cpp <<EOF
void myfunc(int arg1, int arg2)
{
/* do stuff with arg1, arg2 */
}
EOF
g++ -Wmissing-prototypes -c foo.cpp # complains about not valid
g++ -c foo.cpp # no warnings
# Compile in C mode, warning appears as expected:
g++ -x c -Wmissing-prototypes -c foo.cpp
3 Réponses :
Prendre la déclaration suivante par exemple: P> -wmissing-prototypes code> n'est pas applicable pour C ++, car C ++ nécessite toujours des prototypes.
void foo();
foo code> peut être appelé avec n'importe quel nombre et type d'arguments. Li>
foo code> ne prend aucun argument (erreur de compilation si des arguments sont passés). LI>
ul> p>
Lorsque vous compilez un fichier avec En d'autres termes, vous ne pouvez pas "allumer ce avertissement em>" en C ++, car "prototype manquant" est toujours une erreur em> in c ++. P>
En langage C Une fonction La déclaration em> peut être un prototype em> ou non un prototype, d'où la nécessité d'un terme supplémentaire pour distinguer les autres. Dans les déclarations de fonctions C ++ sont toujours em> "prototypes" (du point de vue de c), donc en C ++, il n'ya tout simplement pas besoin de ce terme supplémentaire. Dans les déclarations de fonctions C ++ sont simplement les déclarations de fonction em>. Qui dit simplement tout. P>
Le but de En d'autres termes, si vous avez défini une fonction dans certains fichiers de mise en œuvre, vous avez oublié d'inclure un prototype de cette fonction dans certains fichiers d'en-tête, vous n'aurez aucun avertissement du compilateur jusqu'à ce que vous n'essayiez pas appeler < / em> cette fonction. Peu importe que votre code soit C ou C ++, que vous utilisiez Mais une fois que vous essayez d'appeler une fonction sans prototype, le compilateur C signalera un avertissement (si vous avez utilisé .cpp code> extension, il est compilé sous forme de code C ++ par défaut. En C ++ Langue, l'exigence de déclarations de fonction est obligatoire et obligatoire. Il ne sert à rien de faire un
-wmissing-prototypes code> pour C ++. P>
EDIT: strong> Après avoir lu votre commentaire, je suis arrivé à la conclusion que vous devez avoir mal compris le sens et le but de l'option -wmissing-prototypes code> et l'avertissement correspondant . Remarque, cette option ne vérifiera pas si vous avez inclus des prototypes de toutes vos fonctions dans un fichier d'en-tête. Il n'y a aucune option pour le faire dans GCC, que vous utilisiez C ou C ++. p>
-wmissing-prototypes code> est différent. Cette option ne fonctionne que lorsque vous appelez em> une fonction sans prototype visible au point de l'appel. En C, le langage C est légal, mais si vous souhaitez un avertissement dans ce cas, vous utilisez
-wmissing-prototypes code> option. Dans la langue C ++ appelant une fonction qui n'a aucune déclaration visible ("prototype") au point de l'appel est toujours une erreur immédiate, c'est pourquoi les compilateurs C ++ n'ont pas besoin d'une telle option que
-wmissing-prototypes code >. P>
-wmissing-prototypes code> ou non ... jusqu'à ce que vous essayiez d'appeler la fonction, il n'y aura pas d'avertissement. p>
-wmissing-prototypes code>) et C ++ compiler signalera toujours une erreur. del > p>
Ce n'est pas vrai, du moins pas avec GCC. Il sera heureux de compiler un fichier .CPP qui a des fonctions sans prototype. Cela signifie que je peux avoir FOO.CPP avec une fonction implémentée sous forme de vide MyFunc (int arg1, int arg2) {/ * Utilisez arg1 et arg2 * /}, mais si le fichier d'en-tête indique le vide Myfunc (int Arg1); Ensuite, tous les appelants seront hors de synchronisation et il n'y aura pas d'indication de celui du compilateur!
@ERIC: Désolé, mais ce que vous dites n'a aucun sens. Premièrement, en C ++, le compilateur ne vous permettra pas i> d'appeler une fonction non déclarée, une période. Deuxièmement, votre exemple avec myfunc code> est complètement irrevant. En C ++
myfunc (int, int) code> et
myfunc (int) code> sont deux fonctions complètement différentes i> (surchargées). Les appelants ne seront pas «hors synchronisation». Les appelants appelleront simplement une autre fonction (en supposant que ce soit défini). C'est une question de votre intention, pas une question de «indication du compilateur». Il n'y a pas d'erreur / problème en C ++, alors qu'attendre quelque chose du compilateur serait plutôt étrange.
Si vous oubliez de définir myfunc (int) code>, alors vous obtiendrez une erreur de la lieur, bien sûr. Mais encore une fois,
myfunc (int) code> et
myfunc (int, int) code> sont deux fonctions indépendantes complètement différentes en C ++. Il est de votre responsabilité de déclarer et d'appeler le bon. Si vous appelez
myfunc (int) code>, le compilateur supposera que c'est ce que vous vouliez. Si vous vouliez appeler
myfunc (int, int) code> mais appelé
myfunc (int) code> par erreur ... Désolé, le compilateur ne peut pas lire votre esprit pour personnaliser lequel vous En fait, voulait i> appeler.
Ok, alors j'aurais une erreur de la liaison. C'est mieux que rien, mais cela rend les problèmes plus difficiles à suivre que nécessaire B / C L'erreur pointe au mauvais emplacement et que cela suppose que je reçois même réellement la phase de liaison finale. Par exemple: Si je travaille sur une bibliothèque partagée et changez l'une des interfaces, le problème peut ne pas apparaître jusqu'à ce que je puisse considérablement plus tard lorsque je (ou quelqu'un d'autre même!) va et essaie d'utiliser la bibliothèque partagée pour relier un programme final . Au lieu de cela étant un correctif de 30 secondes parce que j'ai remarqué le droit lors de la compilation de ce fichier, cela pourrait prendre des jours!
@ERIC: Voir la section "Modifier" de ma réponse.
Err ... La page de l'homme de la GCC dit clairement "définie", non "appelée" pour -wmissing-prototypes: "Avertissez si une fonction globale est définie sans une déclaration de prototype précédente." Essayez l'exemple que j'ai inclus dans la question; Il sera clair que je ne suis pas mal compris la signification de l'option. L'option qui allume des avertissements lorsque appeler i> une fonction est -Wimplicit-fonction-déclaration (AKA -WIMPLIT)
@ERIC: Oh, mon erreur. Merci d'avoir refusé cela pour moi. Dans ce cas ... Eh bien, je suppose que l'option aurait effectivement un sens pour C ++. Pourrait-il être que c'est juste orthographié différemment? (Puisque C ++ n'utilise normalement pas le terme "prototype")
Je pense que ce n'est tout simplement pas pris en charge. J'ai enfin trouvé un vieux bug "fermé" ( gcc.gnu.org/bugzilla/ show_bug.cgi? id = 13687 ) qui se plaint de ce même problème. J'ai ouvert un nouveau bogue ( gcc.gnu.org/bugzilla/show_bug.cgi? ID = 43272 ) avec ce qui est, espérons-le, un argument plus persuasif pour permettre cet avertissement.
@ Scientifique: Mais encore une fois, l'objectif ultime du -wmissing-prototypes code> est d'empêcher les appels sans prototype. C'est à dire. Le
-wmissing-prototypes code> est lié à
-Wimplicit code>. Le premier est prévu comme une mesure préventive, tandis que la dernière est davantage un rapport perfectif immédiat. Enc ++ à nouveau, toute la question d'un "appel sans prototype" est différente. Vous ne pouvez tout simplement pas faire un tel appel en C ++, c'est pourquoi
-wmissing-prototypes code> pourrait être considéré comme significativement moins utile en C ++.
IMO, c'est un argument d'avoir à avoir des prototypes -WMISSING! Si vous ne pouvez pas appeler un appel en C ++ avec un prototype, le compilateur devrait vous dire que vous manquez le prototype! Et cela devrait le faire pour le moment pendant une construction lorsque vous pouvez réellement faire quelque chose à ce sujet. En C ++, -wmissing-prototypes n'empêche pas simplement les appels sans le prototype, mais il empêcherait les appels avec le mauvais prototype.
Avez-vous essayé -wmissing-Déclarations? Cela semble fonctionner pour g ++ et détecter le cas d'erreur que vous décrivez. Je ne suis pas sûr de la version dont ils l'ont ajouté, mais cela fonctionne pour moi dans 4.3.3. P>
Merci, cela semble être ce dont j'ai besoin. Maintenant, j'ai juste besoin de déterminer comment mettre à niveau la version de GCC sur mes machines RHEL5.
Je suis confus comment ce fichier FOO.CPP doit jamais donner un avertissement "Aucun prototype". Votre définition de fonction indiquée est i> un prototype.
Peut-être plutôt que de simplement demander comment allumer des avertissements qui semblent avoir aucun sens en C ++ (comme indique l'avertissement), vous postez un exemple quel type d'erreur est que vous souhaitez attraper que le compilateur C ++ ne veut pas Catch ("garantissant que
const char * code> est correctement manipulé")?
Où voyez-vous un prototype? Le code exemple n'inclut pas un fichier d'en-tête, et il n'a pas de ligne de prototype distincte dans le fichier FOO.CPP.
Le problème que je veux attraper est où quelqu'un change la définition d'une fonction dans un fichier .CPP, mais oublie de modifier le fichier d'en-tête. Avec l'avertissement, que i> développeur obtiendrait une erreur (en supposant que je possède également -werror sur), et il serait capable de le réparer tout de suite. Sans l'avertissement, un autre développeur i>, qui utilise la bibliothèque, le premier développeur a écrit, aurait une erreur difficile à suivre lors de la liaison de son programme, et une fois qu'il a choisi ce qui ne va pas les frais généraux de la réparation du problème. est énormément augmenté.