Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

déclaration tableau C99 taille variable

36 réponses
Avatar
Nicolas Aunai
salut,

je viens d'apprendre avec surprise que je peux faire :

int tab[x]; avec x une variable dont la valeur est acquise pendant
l'execution...


moi qui banissais totalement ce genre de chose, et hurlais après qqn
dès que je le voyais faire ça... je ne sais plus quoi penser...

pourquoi a-t-on permi ça en dans la norme C99 ?

si x est mal controlé dans mon programme, genre si a un moment j'ai
x=319391929919291929, ça me parait très dangereux


explications ?

--
Nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@hotmail.com

10 réponses

1 2 3 4
Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Nicolas Aunai ç wrote:

je viens d'apprendre avec surprise que je peux faire :

int tab[x]; avec x une variable dont la valeur est acquise pendant
l'execution...


En C99, oui.

moi qui banissais totalement ce genre de chose, et hurlais après qqn
dès que je le voyais faire ça... je ne sais plus quoi penser...


Moi, pareil. Je continue de penser que c'est inutile et dangereux, mais on ne
pas pas demandé mon avis pour écrire C99!

pourquoi a-t-on permi ça en dans la norme C99 ?


Pétage de plomb, excès de bière, de coke... probablement...

si x est mal controlé dans mon programme, genre si a un moment j'ai
x19391929919291929, ça me parait très dangereux


Même pour une allocation 'normale', on ne sait jamais si le tableau est
valide ou non. Bref, pour moi, c'est inutilisable. malloc()/free() fait déjà
le boulot proprement depuis C90 (et même avant).

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
pierrot
Nicolas Aunai wrote:
salut,

je viens d'apprendre avec surprise que je peux faire :

int tab[x]; avec x une variable dont la valeur est acquise pendant
l'execution...


moi qui banissais totalement ce genre de chose, et hurlais après qqn dès
que je le voyais faire ça... je ne sais plus quoi penser...

pourquoi a-t-on permi ça en dans la norme C99 ?

si x est mal controlé dans mon programme, genre si a un moment j'ai
x19391929919291929, ça me parait très dangereux


explications ?



si je ne me trompe,
int tab[x]
c'est en gros equivalent a un
add %ebp,x


prenons ce petit bout de code

+++++

int f( int l ) {
int tab[l];
fprintf( stdout, "tab == %p for %dn", tab, l );
}

int main( int argc, char ** argv ) {
int l = atoi( argv[1] ), j = atoi( argv[2]), i = 0;
while( i < l ) {
f( i += j );
}
}

+++++++

eh bien
$ ./exe 20000000 1024
......
tab == 0xbf807640 for 2088960
tab == 0xbf806640 for 2089984
tab == 0xbf805640 for 2091008
tab == 0xbf804640 for 2092032
tab == 0xbf803640 for 2093056
tab == 0xbf802640 for 2094080
tab == 0xbf801640 for 2095104
zsh: segmentation fault ./exe 20000000 1024

Bien sur, cette valeur de 2095104 n'a rien de normative ... elle dépend
des valeurs par défaut de ton systeme pour ce qui est de la pile par exemple
Mais a mon sens : ca va planter a moins que tu ne mettes en place des
mécanismes de défense de la pile

Et pourquoi c'est autorisé en C99 ? ben pourquoi pas ... c'est pas plus
laid que
#define N 1024
int tab[N]
Le seule différence, c'est que dans le
add %ebp,x
le x est pas fixe

--
Pierrot

-------------------

si vous voulez me repondre par mail, veuillez retirer les marrons du feu

Avatar
espie
In article ,
Nicolas Aunai ç wrote:
salut,

je viens d'apprendre avec surprise que je peux faire :

int tab[x]; avec x une variable dont la valeur est acquise pendant
l'execution...


moi qui banissais totalement ce genre de chose, et hurlais après qqn
dès que je le voyais faire ça... je ne sais plus quoi penser...

pourquoi a-t-on permi ça en dans la norme C99 ?

si x est mal controlé dans mon programme, genre si a un moment j'ai
x19391929919291929, ça me parait très dangereux



Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
non standard, et qui nuit fortement a la sante.

Au moins, avec une construction comme int tab[x]; on informe le
compilateur de ce qu'il est cense faire, et ca fait du code nettement
plus portable qu'avec alloca().

(enfin a terme, quand on aura suffisamment de compilos C99 dans la nature).

Avatar
Marc Boyer
Marc Espie wrote:
Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
non standard, et qui nuit fortement a la sante.


Mais alloca a quand même la gentillesse de signaler
son échec à ma connaissance.

Au moins, avec une construction comme int tab[x]; on informe le
compilateur de ce qu'il est cense faire, et ca fait du code nettement
plus portable qu'avec alloca().


Portable, mais en espérant ne pas avoir de débordement de pile.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Marc Boyer
Nicolas Aunai wrote:
pourquoi a-t-on permi ça en dans la norme C99 ?


Parce que c'est facile à implémenter ? Parce qu'on cherchait
des trucs sexy à ajouter au langage C sans ressembler à C++ ?
Parce que M$ a des taupes dans le commité chargés de
rendre le langage C inutilisable ?

En fait, il existe une fonction alloca qui fait
quasiment la même chose, mais qui n'était pas standard.
Comme elle est très largement utilisée, le commité a
surement voulu intégrer une fonctionnalité équivalente
dans la norme.
De plus, de tête, cette possibilité existe aussi
dans des langages comme Ada.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Laurent Wacrenier
Marc Boyer écrit:
Marc Espie wrote:
Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
non standard, et qui nuit fortement a la sante.


Mais alloca a quand même la gentillesse de signaler
son échec à ma connaissance.


En théorie, oui. En pratique ça fait planter le programme.


Avatar
DINH Viêt Hoà

Marc Boyer écrit:
Marc Espie wrote:
Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
non standard, et qui nuit fortement a la sante.


Mais alloca a quand même la gentillesse de signaler
son échec à ma connaissance.


En théorie, oui. En pratique ça fait planter le programme.


tout comme les malloc() sur unix avec "Out of Memory Killer"

d'ailleurs, bizarrement, alloca() n'apparaît pas dans les standards POSIX.
Enfin à la fin de tout man alloca(), on trouve la notifice :

<<
The alloca function is machine and compiler dependent. Its use is dis-
couraged.




--
DINH V. Hoa,

"s/^((.|[^[]|[(^.|[^^])[^]]*])*)([^*[])/14/"
-- Stéphane CHAZELAS



Avatar
Marc Boyer
Laurent Wacrenier wrote:
Marc Boyer écrit:
Marc Espie wrote:
Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
non standard, et qui nuit fortement a la sante.


Mais alloca a quand même la gentillesse de signaler
son échec à ma connaissance.


En théorie, oui. En pratique ça fait planter le programme.


Ah... Je vois l'ampleur du problème...

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(



Avatar
Laurent Wacrenier
Emmanuel Delahaye écrit:
Moi, pareil. Je continue de penser que c'est inutile et dangereux, mais on ne
pas pas demandé mon avis pour écrire C99!


C'est tout de même bien pratique : c'est plus rapide et la mémoire est
libérée comme par magie lorsqu'on quite la fonction, notement avec
longjmp.

Avatar
Laurent Wacrenier
Marc Boyer écrit:
Ah... Je vois l'ampleur du problème...


Ça a tendance à faire une violation de segment, qui est
interuptible. Dans ce cas il vaut mieux quitter proprement. Un peu
comme quand malloc renvoie NULL.

1 2 3 4