8
votes

Comment vous manquer des prototypes de prototypes de G ++?

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: xxx pré>

peut me dire:
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>

EDIT: strong> p>

Voici un exemple de coupe et de pâte: 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


4 commentaires

Je suis confus comment ce fichier FOO.CPP doit jamais donner un avertissement "Aucun prototype". Votre définition de fonction indiquée est 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 * 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 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 , 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é.


3 Réponses :


8
votes

-wmissing-prototypes code> n'est pas applicable pour C ++, car C ++ nécessite toujours des prototypes.

Prendre la déclaration suivante par exemple: P>

void foo();
  • in c, foo code> peut être appelé avec n'importe quel nombre et type d'arguments. Li>
  • en C ++, foo code> ne prend aucun argument (erreur de compilation si des arguments sont passés). LI> ul> p>


0 commentaires

11
votes

Lorsque vous compilez un fichier avec .cpp 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 pour C ++.

En d'autres termes, vous ne pouvez pas "allumer ce avertissement " en C ++, car "prototype manquant" est toujours une erreur in c ++.

p. comme une note latérale: la notion de prototype est spécifique au langage C uniquement. Il n'y a pas de "prototypes" en C ++.

En langage C Une fonction La déclaration peut être un prototype 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 "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 . Qui dit simplement tout.

EDIT: 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 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 ++.

Le but de -wmissing-prototypes est différent. Cette option ne fonctionne que lorsque vous appelez 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 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 .

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 -wmissing-prototypes ou non ... jusqu'à ce que vous essayiez d'appeler la fonction, il n'y aura pas d'avertissement.

Mais une fois que vous essayez d'appeler une fonction sans prototype, le compilateur C signalera un avertissement (si vous avez utilisé -wmissing-prototypes ) et C ++ compiler signalera toujours une erreur.


10 commentaires

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 d'appeler une fonction non déclarée, une période. Deuxièmement, votre exemple avec myfunc est complètement irrevant. En C ++ myfunc (int, int) et myfunc (int) sont deux fonctions complètement différentes (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) , alors vous obtiendrez une erreur de la lieur, bien sûr. Mais encore une fois, myfunc (int) et myfunc (int, int) 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) , le compilateur supposera que c'est ce que vous vouliez. Si vous vouliez appeler myfunc (int, int) mais appelé myfunc (int) par erreur ... Désolé, le compilateur ne peut pas lire votre esprit pour personnaliser lequel vous En fait, voulait 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 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 est d'empêcher les appels sans prototype. C'est à dire. Le -wmissing-prototypes est lié à -Wimplicit . 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 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.



4
votes

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.


1 commentaires

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.