4 votes

Puis-je savoir si la variable a changé de valeur sans la comparer à la valeur précédente dans un appel de fonction C ?

Pour le code C/C++ suivant

void fun(int* x)
{
    //SOMECODE;//WITHOUT SAVING PREVIOUS VALUE
    if(SOME CONDITION)
    printf("VALUE OF X IS DIFFERENT THAN PREVIOUS CALL \n");
}

int main()
{
    int a;
    a=9;
    fun(&a);
    a=12;
    fun(&a);
    return 0;
}

Existe-t-il une fonction ou un drapeau qui nous informe si une variable a été modifiée ou non ? S'il y a une solution, veuillez répondre

5voto

mikyra Points 3595

Sans fournir de code supplémentaire pour stocker le paramètre pendant le site "dernier l'appel à votre fonction, il n'y a aucune chance de détecter si elle a été appelée avec la même valeur ou une autre.

Comme le actuel La valeur de x vivra sur la pile mais elle sera complètement perdue une fois que votre appel de fonction sera terminé.

Dans le pré-multi-threading ère simplement en utilisant une variable statique pour mettre en cache la valeur de x lors de la dernière exécution de votre fonction. func pourrait (presque) avoir résolu votre problème :

void fun (int x) {
    static int old_value = VALUE_INVALID;

    if(x != old_value)
       printf("VALUE OF X IS DIFFERENT THAN PREVIOUS CALL \n");

    old_value = x;
}

Le seul problème qui subsiste avec cette approche est la ré-entrance - ce qui signifie que la valeur mise en cache peut être altérée si func est appelé dans un gestionnaire de signaux.

Si l'on fonctionne dans un multithreading application vous devez en outre prévoir une sorte de mécanisme de verrouillage lorsque vous utilisez cette approche, sinon vous vous retrouverez tôt ou tard dans la merde.

Il est probable que vous serez de toute façon dans l'embarras dans ce scénario, car vous devrez clarifier ce qui suit "dernier appel à la fonction et à la valeur pendant exécution signifie exactement.

La bonne valeur actuelle est-elle celle du thread A qui est entré dans func avant le thread B mais qui est toujours en train de s'exécuter ou celle du thread B qui est entré après B mais qui a déjà terminé l'exécution de func ?

2voto

Ben Voigt Points 151460

En relisant votre question, vous ne vérifiez pas si une variable change, mais si deux différents les instances d'un même identifiant lexical sont différentes.

Ce n'est pas possible, sauf par comparaison explicite.


Réponse originale concernant la détection des changements d'une variable :

Il n'y a aucun moyen dans le C ou le C++ portable et standard.

Cependant, il existe des moyens spécifiques à l'environnement pour détecter la modification d'une variable. Vous pouvez utiliser les drapeaux de contrôle d'accès de la MMU (par l'intermédiaire de mprotect o VirtualProtect ) pour générer une exception lors de la première écriture, et définir un drapeau sale à l'intérieur du gestionnaire. (Presque tous les systèmes d'exploitation modernes font cela avec les fichiers mappés en mémoire, pour savoir s'il faut les réécrire sur le disque). Ou vous pouvez utiliser un point d'arrêt matériel pour faire correspondre une écriture à cette adresse (les débogueurs utilisent ceci pour implémenter des points d'arrêt sur les variables).

Aucune de ces méthodes ne sera aussi efficace que la comparaison avec l'ancienne valeur. (Mais la comparaison avec l'ancienne valeur manquera les scénarios ABA).

1voto

flyingOwl Points 234

Il n'y a pas de possibilité de vérifier si la valeur actuelle diffère de la valeur envoyée lors du dernier appel.

Au moment de l'exécution, chaque appel à fun() crée un cadre de pile indépendant avec sa propre copie de x . fun() ne peut sauvegarder aucune valeur à l'intérieur de ce cadre de pile (utilisé pour stocker les variables locales) pour un appel ultérieur.

Il n'existe pas non plus de moyen de déterminer si une "variable a changé de valeur sans la comparer à la valeur précédente".

0voto

Sumit Kumar Points 150

Quel est le but de vérifier si la variable a été modifiée ou non ?

Que diriez-vous d'utiliser une structure contenant une variable et un drapeau. Lorsque la variable est modifiée, mettez le drapeau et passez la structure à la fonction. Maintenant, testez le drapeau dans la fonction pour vérifier si la variable est modifiée ou non.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X