existe-t-il un moyen de réinitialiser les variables déclarées comme statiques dans une fonction? L'objectif est de s'assurer que la fonction n'est pas appelée avec des valeurs persistantes d'un appel sans rapport. Par exemple, j'ai une fonction oporologique sur les colonnes d'une matrice.
int foo(matrix *A, int colnum, int rownum){ static int whichColumn; static int *v; //vector of length A->nrows if (A == NULL){ FREE(v); whichColumn = 0; } //do other things }
5 Réponses :
Utilisez une fonction d'initialisateur idempotent et des variables globales à la place.
Par exemple: P> Si votre initialiszer est vraiment idempotent, vous pouvez l'appeler à nouveau pour réinitialiser les variables . P> Si vous Besoin em> Ceci doit être appelé de manière automatiquement, utilisez Toutefois, vous devez noter que si vous devez le faire, vous devez reconsidérer à l'aide de variables code> statiques de fonction de code> et utilisez plutôt des frais frais passés qui sont retournés / écrit et transmis aux appels correspondants suivants. P> p> __ attribut __ ((constructeur)) code> (pour GCC) comme: P> < Pré> xxx pré>
Salut merci pour la réponse. J'ai décidé de suivre les conseils et de ne pas utiliser * V comme une variable statique - à la place, utilisez simplement lescolumns comme une variable StatTC. V fait maintenant partie de la structure comme recommandé par Jesse ci-dessous. Passage (colonne = -1) réinitialise la variable statitique et réinsialise le vecteur de travail. Ensuite, il est mis à jour de manière appropriée pour chaque fois (colonne! = Quelcolumn). Votre autre suggestion semble utile et j'en apprendrai. Merci encore. sm
hmm - Cela semble un peu risqué - pas sûr de sa solution la plus robuste avec les variables globales suspendues
Je recommanderais de la transformer en structure et à écrire une petite fonction d'assistance pour la gestion de la sémantique de ce que vous essayez de faire. Il pourrait renvoyer le tampon si la demande est appropriée pour sa taille ou créer une nouvelle sur demande (et libérer l'ancien) si nécessaire. P>
Whoops, que diriez-vous d'une fonction STRIT + HELPER?
Merci Jesse, j'ai utilisé un hybride des approches TEO comme mon commentaire à BoreAlid indique. "RESET" est toujours géré par la fonction pour masquer les détails à l'extérieur. Je ne connais pas C ++, alors la classe wrapper est donc ootuq.
Une approche que j'ai vue utilisée lorsqu'un module C a été importé sur C ++ consistait à entourer le module entier avec une enveloppe de classe et à remplacer toutes les variables statiques à l'intérieur des fonctions avec des varaibles «globales» non nommées de manière unique. Je ne sais pas un bon moyen d'obtenir un effet similaire pour les projets impliquant plusieurs fichiers source, bien que j'aimerais savoir si l'on existe. J'ai du code système intégré en C, que je simulent en ajoutant des emballages C ++ dans VS2005. Par exemple, j'ai des registres d'E / S définis pour que quelque chose comme TX1CON = 0x5C; se traduirait par quelque chose comme IOMAP (0x251) .p = 0x5c; IOMAP est une propriété qui enverrait "Ecrire 0x5C à l'adresse 0x251" à un programme de simulation matérielle. Cette approche fonctionne bien, mais je ne peux pas faire une réinitialisation propre. Des idées? P>
Un problème avec ceci est que vous vous retrouvez avec un groupe entier plus de fonctions == Code BLOAT. De plus, vous appuyez simplement sur la responsabilité de l'échelle qui vous conduira finalement à la fonction «dieu» anti-motif. Je ne pense pas qu'il y ait une solution «propre» évidente à cela pour une langue non-oop
@HIETT: Dans le scénario particulier, j'ai décrit avec les emballages C ++ dans VS2005, le flucteur de code n'est survenu que dans un contexte de simulation. Depuis que le système réel avait 128k ROM et 4K RAM et que l'environnement de simulation avait des concerts de RAM et, étant donné que le système réel a probablement eu un "code brut" inférieur à 1% aussi vite que l'environnement de simulation, ma préoccupation était d'écrire du code dans un tel manière d'être efficace sur le système réel, sans tenir compte de l'efficacité dans le contexte de la simulation. D'autres situations auraient d'autres exigences.
Une approche qui peut parfois être utile si l'on a besoin d'une méthode de "réinitialisation" pouvant frapper un nombre inconnu de fonctions ou de modules consiste à compter un compteur global pour combien de fois cette méthode de réinitialisation a été appelée, puis à chaque fonction ou le module inclut le code comme: dans certains contextes multi-threading, si l'initialisation des variables statiques peut dépendre de certaines variables globales, on peut souhaiter remplacer le "si" avec un " tandis que"; dans ce cas; Les barrières de mémoire peuvent également être nécessaires dans un tel cas, bien que les exigences exactes varient en fonction de l'environnement de fonctionnement. P> En outre, un autre modèle pouvant être utile au sein de systèmes incorporés serait d'avoir un ceci nécessiterait qu'il n'y ait pas de Plus de 32 ID de module et nécessiteraient qu'ils soient alloués de manière unique en quelque sorte, mais certains systèmes peuvent gérer cela assez bien. Par exemple, un lieur peut permettre de définir une "section de données" de l'adresse 0-31 d'un espace d'adresses indépendant de tout autre; Si chaque module déclare une variable monte-octet dans cet espace d'adresses, la liaison pourrait générer les adresses appropriées pour ces variables. P> p> modules_initialisé sur code> variable globale qui est défini sur 0 par la méthode de réinitialisation globale, puis chaque module commence avec quelque chose comme: p>
Vous pouvez créer votre fonction de telle manière que si vous l'appelez avec des paramètres zéro, il réinitialisera ses variables statiques internes
Voici un exemple: P>
foo(); // internal values would then be reset
N'utilisez pas de variables statiques / globales. Au lieu de cela, passez la fonction un pointeur sur un entier que l'appelant conserve pour préserver l'état entre les appels.
Je viens d'avoir un problème similaire que je devais réinitialiser mes variables statiques mais que dans mon code de test. Mon hack était de définir des pointeurs d'entrée sur NULL, de vérifier cela dans la fonction FUNC, puis de réinitialiser la variable, le cas échéant, en utilisant efficacement une valeur null dans un paramètre existant en tant que drapeau. Un peu malodorant mais ça marche.
Une classe avec des variables de membre statiques serait votre solution idéale, mais avec C (NO OOP) peut-être une structure statique est probablement la solution élégante la plus proche.
Désolé reluez votre message initial plus attentivement - j'ai effectivement proposé la même solution, rapide et sale - ne peut penser à rien de mieux qui serait aussi rapide à mettre en œuvre