6
votes

Ne devrait pas manquer les paramètres de chaîne de format être une erreur de compilation?

Dans les cas où le texte intégral de la chaîne de format est statique et connu à l'heure de la compilation, le paramètre de chaîne de format manquant doit-il être une erreur de compilation de compilation ou, à tout le moins, avertir?

Resharper attrape ceci , mais c'est juste un squiggle souligné. J'avais l'impression que cela déclencherait une erreur de compilation générale: xxx

est un moyen de déclencher un avertissement sur ce type d'erreur sans avoir à exécuter mon code via FXCop ou quelque chose? Même les compilateurs C / C ++ déclencheront un avertissement / une erreur pour un tel bogue clair (bien qu'ils ne vérifient généralement pas la sécurité de type).


17 commentaires

Le compilateur n'analyse pas votre chaîne de format, alors comment est-il censé savoir que vous manquez un paramètre?


string.format ne fait pas partie de la langue de programmation C #. Pourquoi le compilateur se soucierait-il de cela?


Yep, pas un travail de compilateur pour le faire - 'Format' est juste une méthode personnalisée vraiment aussi loin que le compilateur va


Je suis à peu près sûr que le compilateur C / C ++ n'essaye pas votre format Imprimerf ...


C # Compilateur est très limité par rapport à la plupart des C / C ++.


@AGent_L - Faites attention lorsque vous parlez du compilateur C # ici. Eric Lippert pourrait vous attraper et vous gifler avec un poisson.


@Johnsaunders, Nsgaga: un compilateur n'est pas limité à la spécification. Cela peut aller au-delà de cela pour assurer la qualité. C'est pourquoi ils s'appellent des avertissements. M.babcock Avez-vous déjà codé C? Les compilateurs C attrapent même si "Printf" ne fait pas partie de la spécification (et sans-wall, même!): gist.github.com/2407405


@ M.Babcock: Certains compilateurs avertiront des problèmes de compatibilité de type dans les appels vers Printf (VS2010 fait). Cela n'atteint pas tout, mais cela me dit que c'est en fait l'analyse de ma chaîne de format.


@ Mahmoudal-qunsi: Si mon compilateur commence à faire des choses qui ne sont pas dans la spécification, je souhaite le renvoyer et demander un vrai compilateur.


Wow. Je pensais que je l'ai bien fait dans mon cours de compilateurs il y a 35 ans et je pensais que je les utilisais depuis à peu près au même moment. Je pourrais avoir Les compilateurs assermentés optimisent dans les limites de ce que la langue leur dit qu'ils peuvent.


Pourquoi ne pas simplement acheter Restomer et être fait avec? Cela vous dira de ce genre de problème et beaucoup plus. C'est parce que Ce n'est pas le compilateur .


@ M.babcock ouais, mon mauvais. Je me suis souvenu de quelques avertissements sur Printf, mais ils devaient être sur le point de passer des objets non-Pod. Je me laisserais gifler en échange d'une question sur les modèles ou au moins des macros. Alors je suis toujours debout dans mes mots :)


@Johnsaunders a lu mon message. J'ai du Restomer.


Vous avez dit que Resharber le fait, vous n'avez pas dit que vous avez . Il suffit d'augmenter la gravité de Warnig à l'erreur et utilisez le traitement des erreurs à l'échelle de la solution et gardez un œil sur le petit cercle rouge. Vous ne voulez pas de petit cercle rouge.


Les gars, évidemment une réponse de "vous êtes 100% correct" est faux. Il suffit de poster cela pour un rapide 15 points.


Dans quelle question voulez-vous réellement répondre ici? ne devrait pas manquer les paramètres de chaîne de format Strentrer une erreur de compilation? ou est-il un moyen de déclencher un avertissement sur ce type d'erreur sans avoir à exécuter mon code via FXCop ou quelque chose? < / i>. Le premier est en fait limite non constructif.


J'avoue que pour cette raison, je préfère ne pas utiliser string.format et je compose des chaînes avec + . Ce n'est pas bien, mais je préfère ne pas avoir d'erreurs d'exécution.


7 Réponses :


2
votes

It pourrait un avertissement, mais devrait ce qu'il soit? Eh bien, c'est jusqu'à l'équipe du compilateur que je suppose, ce n'est pas comme string.format fait partie de la langue C # . .

Ce n'est pas c; Vous n'appellez pas un comportement non défini ni quoi que ce soit, la méthode peut simplement traiter le paramètre manquant et l'hypothèse est (je suppose ...) que vous allez l'attraper assez rapidement lorsqu'il jette une exception. Il n'y a rien de "dangereux" à ce sujet, c'est juste une erreur logique.


7 commentaires

En fait, cela jette une exception.


J'ai essayé exactement le code Mahmoud fourni et obtenu une exception au format


@AGENT_L: Je l'ai essayé aussi ... mais cela prend un peu à apparaître et j'ai arrêté le programme avant qu'il ne l'a fait: D


@Eds. Toute exception peut être "dangereuse" si au mauvais endroit ou au mauvais moment. Et vous ne pouvez pas «supposer», ce sera rapidement attrapé.


@ Mahmoudal-qunsi: Eh bien, vous testez votre code, non? Si vous laissez cela aller dans la production, vous ne faites pas votre travail (ou du moins, quelqu'un n'est pas). Les exceptions sont préférables aux défaillances silencieux.


Et les avertissements du compilateur sont préférables aux deux.


@ Mahmoudal-qunsi: Veuillez lire: blogs.msdn. COM / B / E Ericgu / Archive / 2004/01/12 / 57985.aspx



2
votes

Je ne pense pas qu'il y ait quelque chose d'autre que ce que vous avez mentionné pour détecter cette condition automatiquement. Quant à la raison pour laquelle cela se produit, la méthode de format est assortie par rapport au (chaîne, paramiques objet []) code> surcharge, que les paramètres sont défini dans la documentation comme suit:

public static string Format(
    string format,
    params Object[] args
)


9 commentaires

Il y a bien sûr "un moyen", ce serait une fonctionnalité qui serait ajoutée au compilateur. IMO, cela ne vaut tout simplement pas la peine, et c'est une sorte de chose étrange à construire dans une caractéristique d'un appel de méthode qui ne fait pas partie de la langue, il n'existe donc pas.


Et il jette une exception BTW.


Eh bien, oui, mais en supposant que vous ne faites pas partie de l'équipe du compilateur, je n'ai aucune suggestion supplémentaire. En tout état de cause, la documentation le définit déjà comme une déclaration légale, cela serait donc au mieux défini comme un avertissement de compilateur.


Quelle est ma question - pourquoi pas un avertissement?


Je n'ai pas essayé, mais oui, cela pourrait lancer une exception de temps d'exécution (par opposition à la compilation). Bien étrange, la documentation indique spécifiquement "zéro ou plus d'objets".


@ Mahmoudal-qudsi Une question seulement MS peut répondre. Peut-être devriez-vous mettre dans une demande de fonctionnalité.


@ Mahmoudal-qunsi: Parce que A) Cela ne fait pas partie de la langue et b) il n'est pas illégal dans la mesure où la langue est concernée. Pourquoi c # la langue savoir quoi que ce soit sur string.format ?


@Eds. Pour la 10ème fois, le travail du compilateur n'est pas simplement de suivre les spécifications, il est de faire tout ce qui est possible pour vous aider à créer un meilleur code et des binaires. Les optimisations ne font pas partie de la spécification, pourquoi votre compilateur les fait-il?


@ Mahmoudal-qunsi: En réalité, il s'agit du travail seulement pour suivre les spécifications. Tout ce qui est le glaçage sur le gâteau. Je ne sais pas où tu as cette idée. Vous dites qu'une fonctionnalité de qualité de vie doit être requise, ce qui est juste idiot. En outre, il ne sert que sur un cas d'utilisation. Si ma chaîne de format est variable, il ne peut rien faire à ce sujet.



-1
votes

Le paramètre "Format" de la méthode n'est pas constant. Tout ce qui n'est pas constant ne peut pas être vérifié au moment de la compilation.

Il peut être composé au moment de l'exécution via diverses méthodes, elle peut même être une entrée d'utilisateur ... (l'horreur!)

C'est pourquoi il n'est pas une erreur de compilation.

EDIT: OK, dans le cas où il s'agit d'une expression constante, elle pourrait être analysée pourrait être analysée et qu'un avertissement pourrait être généré. Mais voici La réponse de Eric Lipert sur une question différente Un peu aplicable: il y a une barre d'avantages sur le coût.

Que ce soit un avantage réel qui vaut la peine de dépenser les scénarios spéciaux de cas pour String.Format (et éventuellement d'autres fonctions de format de chaîne) est ... un appel difficile.


3 commentaires

Eh bien, plusieurs fois, il est constant, auquel cas cela pourrait l'attraper. Ce n'est pas un problème technique, c'est celui de la séparation des préoccupations et de l'utilité. Est-ce vraiment un problème assez important pour justifier l'ajouter au compilateur donné que string.format ne fait même pas partie de la langue? C'est une décision qui a été faite.


@ Jeroenlandheer n'est pas vrai. Exemple simple qui jette une exception et aucun avertissement, même avec consttrings (et je ne sais pas où vous avez le "seul const peut être lu par le bit du compilateur"): const chaîne format = "blabla {0}"; string x = string.format (format);


@ Mahmoudal-qunsi: Vous ne comprenez pas pourquoi seule une expression constante pourrait être analysée par le compilateur? Pourquoi même poser une question si vous connaissez déjà la réponse «correcte» et sont hostiles à quiconque qui n'est pas d'accord?



0
votes

Certains compilateurs C analysdront les chaînes de format, car avoir des chaînes de format qui ne correspondent pas aux paramètres peuvent causer des bugs graves graves - ni même pire, des bugs de sécurité. En C #, cependant, vous obtenez une exception sur le site d'appel, il n'est donc pas critique.

Le compilateur pourrait le faire, mais cela nécessiterait du code pour reconnaître string.format comme cas particulier, et (même pire) aurait besoin de quelqu'un pour écrire un analyseur de chaîne de format dans le compilateur C #. Tout afin qu'il puisse vous avertir du code qui va crancer à chaque fois qu'il est exécuté.

Le gros problème avec c'est que beaucoup de gens compilent avec tous les avertissements et avertissements comme erreurs, ce qui signifie que l'ajout de cet avertissement va briser leur construction. N'importe qui avec une ficelle de mauvais format dans un coin sombre de leur code où il n'est jamais exécuté ne sera soudainement pas en mesure de construire leur produit. Ces personnes vont se plaindre.


2 commentaires

Désolé, mais c'est l'excuse la plus pitoyable que j'ai jamais entendue. C'est exactement le problème: quand c'est dans "un coin sombre de ton code", vous ne l'attrapez pas (probablement) dans les tests, et c'est surtout pourquoi le compilateur devrait lancer une erreur. Si vous aviez un int x = 7/0 dans un coin sombre de votre code, c'est une erreur de compilation. Et vous ne devriez pas être capable d'ignorer les exceptions d'exécution simplement parce qu'elles sont rangées quelque part!


@ Mahmoudal-qunsi: Pourquoi les chaînes de format sont-elles spéciales? Il existe des classes entières d'erreurs d'exécution pouvant être capturées à l'heure du compilateur (par exemple, passez null à des méthodes documentées pour n'accepter NULL). Par votre raisonnement, le compilateur devrait avoir un code spécial pour rechercher tous ceux-ci également - et ceux-ci ne nécessitent pas d'analyseur mini-linguistique spécial.



0
votes

Comme on l'a déjà dit, ce n'est pas quelque chose que le compilateur fait ou devrait s'inquiéter de.

Comment vous attendez-vous au compilateur de se comporter lorsque vous faites quelque chose comme: P>

string format = "{0}";
List<string> parms = new List<string> { "Hello" };

if (DateTime.Now.Second % 2 == 0)
{
    format += " {1}";
    parms.Add("World");
}

Console.WriteLine(format, parms.ToArray());


2 commentaires

Je ne. Mais je m'attends à essayer. C / C ++ fera un meilleur effort pour analyser vos spécificateurs de format de chaîne, et il est beaucoup plus difficile pour eux que ce n'est pour le compilateur C #.


@ Mahmoudal-qunsi: Sauf en C, vous invoquez UB, en C #, le comportement est parfaitement bien défini. C'est plus dangereux dans C, donc ça vaut la peine.



0
votes

Resharper affiche un avertissement pour ce cas: "argument non existant dans la chaîne de formatage".


0 commentaires

-1
votes

J'ai déposé une demande de considération de cette fonctionnalité sur Microsoft Connect, car je pense que

  • Les réponses qui disent que «les gens préféreraient leur code compilent et échouent au moment de l'exécution si c'est un code de code non très chaud» est juste absurde et n'a pas de place dans des langues non interprétées, et surtout non définie sur des langues explicitement définies et sans explicitement définies. Placez une telle importance sur la sécurité de type comme c #.
  • Les réponses disant que le compilateur est physiquement capable de (jamais) déduire la chaîne de format et le tableau des paramètres au moment de la compilation sont également incorrects. Oui, il y a des moments où le compilateur ne peut pas en déduire l'un ou l'autre (ou les deux) au moment de la compilation, et il n'y a rien qui puisse être fait à propos de ceux-ci, mais plusieurs fois, il a toutes les informations complètes à sa disposition.
  • Les réponses qui disent que ceci est tranchant, pas le travail du compilateur juste parce que la spécification ne mentionne pas de lancer un avertissement pour ce type de comportement manquant le fait que la spécification est le minimum d'un compilateur doit mettre en œuvre et le compilateur est gratuit. (et fait en effet une grande, une grande mesure) d'aller au-delà et au-delà de ce n'est pas en conflit avec la spécification.
  • Les réponses disant que les compilateurs C ne font pas cela non plus mal - j'ai Exemples postés autrement .
  • Les réponses disant que l'échantillon de code que j'ai publié ne jette pas une exception au moment de l'exécution est flagreux (bien que la plupart ont été édités depuis).

    à la fin de la journée, c'est un "oui, ça pourrait, non ça ne le fait pas, peut-être qu'il devrait" " J'essayais de m'assurer qu'il n'y avait pas quelque chose que je pourrais installer dans le compilateur (pas de logiciels tiers) pour le rendre plus agressif avec ses avertissements ou s'il y avait une façon de changer mon code Pour faire jeter une exception (par exemple, déclarer tout comme const), mais il s'avère (jusqu'à présent) que ce qui n'est pas possible. Quelle que soit la réponse de l'équipe Visual Studio sur la question que j'ai ouverte sur MS Connect, le fait reste que le compilateur peut attraper une grande exception de formatage de chaînes au moment de la compilation, qu'il serait Soyez un avantage ... mais il reste pour l'équipe VS de déterminer s'il s'agit ou non de quelque chose qui mérite d'être mis en œuvre.


12 commentaires

GCC! = "Compilateurs C en général". Dire "C ne fait pas cela" est tout à fait correct, car ce n'est pas dans la spécification de la langue. Quelqu'un a-t-il affirmé «aucune mise en œuvre du compilateur de C Compiler le fait»? Ce serait une question différente.


Salut Jon. Oui, la citation exacte "Je suis à peu près sûr que le compilateur C / C ++ n'essaye pas non plus votre format Printf ..."


Ensuite, je vous suggère de prendre problème avec qui spécifiquement - et clarifiez vos déclarations propres qui font référence à des éléments tels que "C / C ++ fera le meilleur effort pour analyser vos spécificateurs de format à chaîne" - C et C ++ sont des langues et non des implémentations. Si vous avez dit "certains compilateurs C et C ++", ce serait beaucoup plus précis.


Oui tu as raison. C'était une déclaration imprécise en mon nom. (Bien que l'intention soit claire comme je l'ai dit "C / C ++ fera ... par rapport au compilateur C #" (vs "comparé à C #"). Juste de mauvaise libellé.


Cela suppose toujours qu'il n'y ait que une mise en œuvre du compilateur C # C #, qui n'est pas vrai.


Je pense qu'il est clair que je parle du stock Microsoft C # Compiler (CSC), pour la dernière version de la langue, ciblant la dernière version du temps d'exécution. Bien que , en fait, la plainte détient également bien pour toute version passée de SCC pour toute version d'exécution et le compilateur mono DMCS, trop. Je ne sais pas s'il y en a d'autres, mais c'est tout à côté du point. Honnêtement, j'adore C # et tout cela ne fait que critiquer constructive de rendre toute l'expérience encore plus développée. Je ne sais pas pourquoi tout le monde devient si défensif à ce sujet.


Je ne pense pas que votre ton a aidé, d'être honnête. Je pense que vous auriez pu poser une question similaire de manière plus constructive (avec des commentaires plus agréables) et reçu un soutien plutôt plus important.


J'ai perdu mon sang-froid et je suis désolé. Mais j'étais frustré par la mentalité des hivemind de "défendre C #, ce gars essaie de dire que c ++ est meilleur", sous la forme de (certains) factuellement incorrecte, des réponses précipitées. Si vous vous référez au poste d'origine, c'était très inoffensif, curieux et authentique. Ce n'était pas mon intention de commencer une guerre et je suis désolé que ce soit ce qu'il était devenu.


Je pense que "un bogue clairement clair" n'a pas été trop bien commencé - et je suggérerais que cela implique que le compilateur C # soit vraiment Devrait faire cela (plutôt que ce qu'il ne s'agit que d'une belle fonctionnalité d'avoir) 't aide. Fondamentalement, ceci est une demande Feature , mais vous impliquez que le compilateur est cassé . Lorsque vous avez écrit une question, lisez-la en essayant de vous mettre à la place du public - cela fait toute la différence.


Vous avez raison. Cela pourrait être facilement mal interprété et je ne l'ai pas pensé. Le "bogue flagrant" ne concerne pas le C #, mais en référence à un développeur écrit un code médiocre qui est évidemment buggy lors d'une nouvelle revue. Je pense que vous conviendrez que la ligne de code posté dans l'OP contient un "bogue clairement clair?" J'ai dû être mal compris.


Non, le point est que ce n'est que «clairement claire» avec des informations qui dépend de la connaissance de la BCL - Connaissances qui généralement n'est pas présente. Fondamentalement, ce que vous êtes après est quelque chose comme des contrats de code, mais avec plus d'analyse. Ce n'est tout simplement pas un jeu que le compilateur C # tente de jouer. Il peut s'agir d'une demande de fonctionnalité raisonnable, mais de votre "question" implique un niveau de dédain pour le compilateur C # que je ne pense pas qu'il garantissait ou utile. Il n'est pas non plus clair pourquoi vous étiez "sous l'impression" que la ligne donnée déclencherait une erreur de compilation erreur quand elle ne violera pas les règles de langue.


J'ai zéro dédain pour C # ou son compilateur. J'aime les deux. Je pense juste que ce serait génial d'avoir cette fonctionnalité de là (style de meilleur effort) ou une bonne explication pour pourquoi pas. Je ne vais évidemment pas gagner ici, mais ce n'est que mes deux cents. Et quant à être sous l'impression, j'étais habitué à C # attraper de nombreux insectes et à donner des avertissements au moment de la compilation beaucoup mieux que C / C ++ (mes principales langues de codage). C'est très louange et rien de moins. Fait (IMHO): C # permet généralement d'écrire plus de code sans bug que C / C ++ la première fois. D'où mon "impression".