Je suis à peu près persuadé que ce n'est pas possible, mais au cas où il y aurait une astuce, j'aimerais savoir s'il y a un moyen d'accéder à une variable static déclarée dans une fonction.
J'ai une fonction (dédiée) qui affiche un texte en fading :
Comme vous le voyez, elle est en charge des allocs et des destructions.
Du coup, pour être certain de finir une routine proprement, avec mes libérations en fin de routine, je dois ajouter :
//waiting display statics to be freed.
while(SOFT_dispTextFade(NULL, 0, CEV_COLOR_WHITE));
Ce qui renvient à attendre la fin de l'affichage pour quitter la routine.
Du coup, j'aimerais pouvoir detruire la texture sans attendre, j'ai pensé à ajouter un argument genre "bool kill" et forcer la destruction de la texture, et c'est probablement comme ça que ça va se finir.
La déclaration static dans une fonction, c'est précisément pour avoir une variable statique (emplacement réservé une fois pour toutes, et dont la durée de vie est celle du programme) qui soit visible seulement depuis la fonction locale, donc).
Donc la demande initiale est contradictoire.
Sinon, il faut utiliser des variables globales, déclarées hors des fonctions. (*) Avec un nom bien choisi pour éviter les collisions.
Variable statique, c'est par opposition aux variables automatiques, qui correspondent à des emplacements réservés sur la pile à chaque appel de la fonction oû elles sont déclarées, et restitués automatiquement en ressortant. Ne pas confondre avec allocation dynamique.
(*) je crois qu'on peut déclarer aussi les variables globales comme static, et dans ce cas elles ne sont visibles que dans l'unité de compilation (le source) oû elles sont déclarées, ce qui limite les risques d'utilisation indue. A verifier.
- Edité par michelbillaud 10 décembre 2023 à 9:00:07
(*) je crois qu'on peut déclarer aussi les variables globales comme static, et dans ce cas elles ne sont visibles que dans l'unité de compilation (le source) oû elles sont déclarées, ce qui limite les risques d'utilisation indue. A verifier.
Perso je confirme
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Je suis à peu près persuadé que ce n'est pas possible, mais au cas où il y aurait une astuce, j'aimerais savoir s'il y a un moyen d'accéder à une variable static déclarée dans une fonction.
Je n'ai pas tout compris, mais pour cette question, c'est possible via un pointeur (mais alors quel intérêt d'avoir une variable static si c'est pour y accéder de l’extérieur).
Je n'ai pas tout compris, mais pour cette question, c'est possible via un pointeur (mais alors quel intérêt d'avoir une variable static si c'est pour y accéder de l’extérieur).
L'intérêt de la déclarer static ici est sa rémanence, pas sa portée, ça m'évite d'avoir à créer une structure d'instance (et un type) alors que je n'ai besoin que d'une seule instance.
Comme tu le soulignes, je sais que c'est possible avec un ptr puisque :
int* fooWithStatic(void)
{
static int toto = 23;
printf("toto = %d\n", toto);
return &toto;
}
int main(void)
{
int *ptr = fooWithStatic(),
val = 10;
while (val<15)
{
*ptr = val++;
fooWithStatic();
}
return 0;
}
toto = 23
toto = 10
toto = 11
toto = 12
toto = 13
toto = 14
Process returned 0 (0x0) execution time : 0.184 s
Press any key to continue.
Pour reformuler un peu mieux :
drx a écrit:
Je suis à peu près persuadé que ce n'est pas possible, mais au cas où il y aurait une astuce, j'aimerais savoir s'il y a un moyen d'accéder - DIRECTEMENT - à une variable static déclarée dans une fonction.
Je pensais à un truc dans le genre de :
fooWithStatic->toto
Parce que j'ai peur qu'utiliser un pointeur vers une locale de fonction soit un peu obscur : Ce n'est déjà pas très "typique" et je suis certain que je vais galérer à me relire dans 2 mois avec ma super mémoire de poiscaille.
C'est pour ça que l'option d'une "syntaxe legit" ou du bit "kill" à l'appel de fonction me semblait plus explicite.
Un exemple historique et tragique d'utilisation de variables statiques, c'est la fonction strtok, qui sert à découper une chaîne en une suite d'éléments (tokens).
Elle utilise une variable statique pour mémoriser l'adresse de ce qui reste à analyser (un pointeur de caractères)
Elle a deux paramètres, une adresse de caractères et un ensemble de délimiteurs
Typiquement, la premiere fois qu'on l'appelle, on donne en premier paramètre la chaîne à analyser, et alors son adresse est mémorisée dans le pointeur statique. Les fois suivantes on passe NULL, et l'analyse se fait en utilisant le pointeur statique.
Avec cette astuce géniale (ahem...), c'est pas possible de travailler sur deux chaînes en même temps, et si on a deux threads, c'est la cata. On applaudit très fort (déjà que c'était pas une idée brillante d'avoir une fonction d'analyse qui modifie la chaine à analyser...)
Note : utiliser à la place la version réentrante strtok_r
static char *olds;
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the last string strtok() was called with is
used. For example:
char s[] = "-abc-=-def";
x = strtok(s, "-"); // x = "abc"
x = strtok(NULL, "-="); // x = "def"
x = strtok(NULL, "="); // x = NULL
// s = "abc\0=-def\0"
*/
char *
strtok (s, delim)
char *s;
const char *delim;
{
char *token;
if (s == NULL)
s = olds;
/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0')
{
olds = s;
return NULL;
}
/* Find the end of the token. */
token = s;
s = strpbrk (token, delim);
if (s == NULL)
/* This token finishes the string. */
olds = __rawmemchr (token, '\0');
else
{
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}
(présente les mêmes inconvénients que déclarer la variable static dans la fonction) -----
Complément, un exemple minimal de ce que je racontais plus haut (variables globales statiques)
SI on met ceci dans main.c
extern int x;
int main() {
return x;
}
et que aux.c contient
int x = 123;
tout va bien
$ gcc *.c
$ ./a.out
$ echo $?
123
depuis le main.c on a pu accéder à la variable globale définie dans aux.c
Mais si on met static
static int x = 123;
Les compilations séparées de chaque unité de compilation se passent bien , mais ça proteste au niveau de l'édition des liens
$ gcc -c aux.c
$ gcc -c main.c
$ gcc main.o aux.o
/usr/bin/ld: main.o: attention: réadressage sur « x » dans la section en lecture seule « .text »
/usr/bin/ld : main.o : dans la fonction « main » :
main.c:(.text+0x6) : référence indéfinie vers « x »
/usr/bin/ld: attention: création de DT_TEXTREL dans un PIE
collect2: error: ld returned 1 exit status
Avec static, le nom de la variable globale n'est pas exporté, et donc ne peut pas être référencé par main.c
- Edité par michelbillaud 11 décembre 2023 à 16:23:15
Accès à une variable static d'une fonction.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
Bonhomme !! | Jeu de plateforme : Prototype.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Bonhomme !! | Jeu de plateforme : Prototype.