bonjour à tous,
si j'ai le code suivant :
void f( int size )
{
int tab[size];
...
}
Le compilateur va retourner une erreur, pourtant en assembleur il est tres facile de réaliser le code ci dessus :
:
push rbp
mov rbp, rsp
sub rsp, eax //avec eax = size
pourquoi en C je ne peux donc pas faire ca. Est ce juste une convention ou alors il y a une raison derriere tout ca ?
Merci d'avance pour vos reponses
# Tableau statique
Posté par Cyril Brulebois (site web personnel) . Évalué à 2.
La taille d'un tableau statique doit être connue à la compilation, donc ça ne peut pas dépendre d'un paramètre qui pourrait varier d'un appel à l'autre.
C'est plutôt
malloc
(ou autre technique assimilée) que l'on utilisera pour gérer un tableau de taille variable.Debian Consultant @ DEBAMAX
[^] # Re: Tableau statique
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 5.
ou utiliser un compilateur C datant de moins de 20 ans supportant le C99 (voir mon commentaire) ^
[^] # Re: Tableau statique
Posté par David Marec . Évalué à 3.
Il ne s'agit pas seulement du compilateur, mais de tout l'environnement, la toolchain.
On ne peut pas compiler le noyau linux ou un module en C11 par exemple, même avec GCC8.
Et n'essayez pas d'introduire une déclaration de variables dans vos boucles, vous allez vous faire engueuler par Linus.
[^] # Re: Tableau statique
Posté par Tonton Th (Mastodon) . Évalué à 3.
$ man 3 alloca
# Les différentes types d'allocation
Posté par nico4nicolas . Évalué à 2.
Pour comprendre le problème, il faut savoir qu'il y a 3 types d'allocations de mémoire possibles, cette page wikipedia le décrit assez bien :
Une variable déclarée dans une fonction sera allouée dynamiquement et gérée de façon automatique (déallocation lors de la fin d'exécution du bloc). La question posée est donc, pourquoi est-ce que l'allocation dynamique automatique doit être de taille fixe ?
Pour le cas d'un tableau, il faut avoir en tête ce qu'est un tableau et en C : c'est un pointeur. L'indice de ton tableau est l'offset du pointeur. Ainsi, pour que l'illusion d'avoir un tableau fonctionne, il faut que les données soient organisées de façon ordonnée dans la mémoire.
De façon schématique, ça ressemble à ça :
| tab[0] | tab[1] | … | tab[size-1] |
Tant qu'il n'y a "rien" derrière ton tableau, tu pourrais l'agrandir mais si une variable vient s'ajouter derrière, le tableau ne pourra plus être agrandi. Comme ces allocations sont gérés dynamiquement, il n'est pas possible de pouvoir garantir l'agrandissement d'un tableau.
[^] # Re: Les différentes types d'allocation
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 4.
C'était vrai avec l'ANSI C, ce n'est plus exact avec le C "d'aujourd'hui" (C99 & +), qui supporte les variables length array dans certaines conditions (pas dans les structures), ou les extensions GCC qui le supportent quasiment partout.
Après c'est un trade-off en performances qui ne convient pas à Linus pour le kernel par exemple, personnellement je pense que si ses arguments sont surement vrai aujourd'hui ils sont aussi probablement corrigeable, et qu'une facilité et uniformité d'écriture apporte un plus en sécurité mais bon, le kernel est maintenant VLA-free depuis plus d'un an.
# C99: Variable Length Array
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 5.
Alors tu peut le faire et ça marche très bien, si ton compilateur supporte la norme C99 et il y en a un paquet:
Ref VLA:https://godbolt.org/z/BVuDxz
https://en.wikipedia.org/wiki/Variable-length_array
https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
[^] # Re: C99: Variable Length Array
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 3.
A savoir que l'équipe du kernel linux à "récemment" introduit un programme de suppression de tout code VLA pour des raisons de performances et de sécurité (https://lkml.org/lkml/2018/3/7/621)
[^] # Re: C99: Variable Length Array
Posté par David Marec . Évalué à 2.
Pour être plus précis, il ne s'agit pas d'un programme, mais d'une option de GCC :
Wvla
.- qui existe aussi pour CLang.-
[^] # Re: C99: Variable Length Array
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 2.
Je ne parle pas de l'ajout de-Wvla mais bien du processus qui a précédé de modification du code pour enlever les différents usages de vla. (ie je ne parlais pas d'un programme au sens informatique)
[^] # Re: C99: Variable Length Array
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 3.
Autre note: le VLA est possible en C / via C99 mais pas en C++
[^] # Re: C99: Variable Length Array
Posté par gUI (Mastodon) . Évalué à 3.
Comment marche le
free()
? Il faut que tu penses à l'écrire ou c'est "auto-magique" ?En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: C99: Variable Length Array
Posté par Kerro . Évalué à 4.
Ce sont des variables donc pas possible d'utiliser
free()
.C'est alloué sur la pile, donc c'est automatiquement perdu lors du retour de la fonction.
# Convention
Posté par gUI (Mastodon) . Évalué à 3. Dernière modification le 12 septembre 2019 à 13:38.
Oui pour moi c'est plutôt une volonté de convention : le tableau est de taille statique point. Apparemment ça a bougé en C99, mais l'idée de base doit être par là.
Ensuite le C étant quand même assez fun, rien ne t'empêche de faire ton malloc puis d'utiliser le tableau.
Tu as écris le
malloc()
, tu as donc une chance de penser à écrire lefree()
:)(j'ai même pas compilé ce code, j'espère ne pas dire de grosses conneries !!!)
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Convention
Posté par David Marec . Évalué à 4.
Ça devrait fonctionner comme ça.
J'aurais casé un
calloc
pour que ça fasse encore plus tableau, par contre.[^] # Re: Convention
Posté par Anthony Jaguenaud . Évalué à 3.
Tu as oublié la désallocation :'(
[^] # Re: Convention
Posté par gUI (Mastodon) . Évalué à 2.
Exactement, et en plus j'en parle !
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Convention
Posté par David Marec . Évalué à -1.
Ou pas …
Sur les systèmes les plus utilisés, dont Linux, la libération sera effectuée de toute façon en sortie de programme.
Tant que l'allocation est contrôlée, la libération est inutile.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.