J'ai des zillions de my_printf () appels de fonction dans un vaste programme. Je veux maintenant les convertir, de sorte que la fonction prend un nouvel argument entier (appelez-le x) sans avoir à modifier les zillions des appels. Si my_printf n'a jamais pris exactement un argument de chaîne, je pourrais faire quelque chose comme ceci:
#if BELT_AND_BRACES_DIAGNOSTIC_MODE
#define function(x) _function(__FILE__,__LINE__,x)
#else // speed critical optimised mode
#define function(x) _function(x)
#endif
#if BELT_AND_BRACES_DIAGNOSTIC_MODE
void _function(char *file,int line,int x)
#else
void _function(int x)
#endif
{
// stuff
#if BELT_AND_BRACES_DIAGNOSTIC_MODE
if (something_went_wrong)
{
printf("Cock up in function when called from %s line %d\n",file,line);
}
#endif
}
6 Réponses :
La meilleure chose à faire est bien sûr de mordre la balle et de modifier le code. Sinon, vous créez un "mystère", qui doit être résolu par tous les futurs responsables du code. Même si ce n'est que vous, c'est exactement le genre d'astuce intelligente que vous oublierez tout. Ça suce de revenir et d'être perplexe par d'étranges macros apparentes inutiles. P>
Cela dit, si vous utilisez une boîte à outils GNU, vous pouvez peut-être examiner en utilisant Varargs Macros . P>
+1 pour mordre la balle. Avec les éditeurs d'aujourd'hui avec un support de refactoring, etc., vous devriez vous rire. Heck, mon éditeur de programmation Il y a 15 ans pourrait facilement effectuer une recherche globale et remplacer les fichiers spécifiés par Wildcard sur un arborescence de répertoire entier, avec et sans mes prévisualiser les résultats en premier. (Et si vous pensez macro, vous pouvez simplement le faire aveugle.)
+1. Regardez-le comme une opportunité d'apprentissage pour vraiment vous accéder à ce qu'un éditeur moderne peut faire (ou si vous êtes assez long, quel vim ou vos emacs peuvent faire - et ils peuvent faire des choses que Visual Studio ne fait que attraper avec ...).
Si le code peut être compilé sous forme de code C99, vous pouvez définir un macro variable
#define my_printf(str, args...) _my_printf(x, str, ##__VA_ARGS__)
C'est GNU, pas C99 - la version C99 lirait définir mon_printf (str, ...) _my_printf (x, __va_args __) code>; Gardez à l'esprit que vous devez fournir un argument au lent
De plus, vous et moi oubliés de passer sur str code>; Je pense que la meilleure approche serait de supprimer le str code> entièrement et simplement d'utiliser définir mon_printf (...) _my_printf (x, __va_args __) code> afin que vous puissiez l'appeler sans La fonction de la fonction même dans la version C99
Le problème est maintenant résolu. J'utilise Dev-Studio 2008 et la chose VA_ARGS B> a fonctionné un traitement - mais je ne suis pas sûr de quelle réponse à la marque est correcte, car aucun d'entre eux ne sont vraiment compensés. La réponse de Dwind implique que je dois utiliser GNU et la réponse de Phillipe ont aussi des erreurs.
@Mick: J'ai ajouté une réponse avec quelques détails sur le problème avec les listes d'arguments vides et les virgules suivantes: Stackoverflow.com/questions/1491749/...
Strangement assez de GCC compilé la formulaire ## args avec STD = C99; Je pensais que cela supprima les extensions GNU (Onlt Tetsed avec GCC V3.4.3). Merci, je l'ai réparé.
@Philippe: utilisez -std = c99 -pedantique code> pour obtenir les avertissements
Je devais remplacer ## VA_ARGS B> par # SARGS pour faire ce travail.
@jbochi quel compilateur utilisez-vous?
si my_printf code> prend déjà un nombre variable d'arguments, je ne sais pas pourquoi vous devez envelopper "un autre argument" dans une macro ... insérez simplement les nouveaux appels avec l'argument supplémentaire et être fait avec elle; Les anciens appels devraient toujours fonctionner comme prévu. P>
pas avec des macros C89 standard, vous ne pouvez pas. Cependant, vous pouvez obtenir le même effet à l'aide de fonctions, en rompant la partie principale de votre (ce genre de chose est pourquoi em> ces vidéations de toutes les fonctions de varargs standard existent.) p> p> My_Printf code> dans une fonction vmy_printf code>, analagous dans la norme vprintf code >:
Vous pouvez utiliser C99 variadic macros: comme Mise en œuvre de Microsoft Les virgules suivantes, l'argument mais ceci conduirait à une erreur de syntaxe dans la norme C lorsqu'il serait appelé sans arguments variadiques p> ou une liste d'arguments vide p> donc , J'irais avec la première version. P> p> STR CODE> peut être ajouté explicitement p>
Une solution simple à ce problème est ...
my_printf((any number of arguments))