2012-04-19 5 views
3

Je calcule dynamiquement la taille d'un tableau. Quelque chose comme:ISO C90 interdit tableau de longueur variable

void foo(size_t limit) 
{ 
    char buffer[limit * 14 + 1]; 
} 

Mais compilateur GCC dit:

error: ISO C90 forbids variable length array ‘buffer’ 

recherche sur SO J'ai trouvé this answer:

C99 §6.7.5.2:

Si la taille est une expression qui n'est pas une constante entière express ion ... ... chaque fois qu'il est évalué, il doit avoir une valeur supérieure à zéro.

Alors, je l'ai fait la nouvelle déclaration de la variable de type limite de taille à:

void foo(const size_t limit) 

Mais il continue de donner un avertissement pour moi. Est-ce un bug du GCC?

+7

Eh bien, 'C90! = C99'. – user7116

+1

Déclarer 'taille_t limite' comme' const' ne change rien. C'est toujours un tableau de longueur variable puisque la taille est déterminée à l'exécution. – Mysticial

+0

GCC vous dit qu'avec les options de ligne de commande que vous utilisez, il compile par rapport à la norme C90 par défaut. Le paragraphe que vous avez cité provient de C99. C'est la cause de votre problème, pas le type de 'limite '. –

Répondre

6

const -qualifier une variable ne fait pas de celle-ci une constante de temps de compilation (voir C99 6.6 §6 pour la définition d'une expression de constante entière ), et avant l'introduction des tableaux de longueur variable avec C99, les tailles de tableaux devaient être des constantes de compilation.

Il est plutôt évident que const -qualifier une variable n'en fait pas une constante de compilation, en particulier dans le cas de paramètres de fonction qui ne seront pas initialisés avant l'appel de la fonction.

Je vois les solutions suivantes à votre problème:

  • compiler votre code comme C99 via -std=c99 ou -std=gnu99
  • affecter votre tampon via malloc()
  • utilisation alloca() si elle est disponible, ce qui est le plus proche, vous pouvez arriver à des tableaux de longueur variable avec C90
  • choisir une taille maximale de la mémoire tampon qui est toujours utilisée et échouer si l'argument limit donné déborde

Comme une note de côté, même si C99 permet tableaux de longueur variable, il est toujours interdit d'utiliser la valeur d'une variable entière avec la durée de stockage statique que la taille d'un tableau avec une durée de stockage statique, quelle que soit const -Qualification : Bien que rien ne l'empêche en principe si la variable entière est initialisée dans la même unité de traduction, vous devez avoir des variables de cas particulier avec une définition visible de celles dont la définition réside dans une unité de traduction différente et doit désactiver définitions ou nécessitent plusieurs passes de compilation car la valeur d'initialisation d'une variable provisoirement définie n'est pas connue tant que l'ensemble de l'unité de traduction n'a pas été analysé.

4

c90 n'autorise pas les matrices de longueurs variables. Cependant, vous pouvez utiliser c99 gcc ompiler pour que cela fonctionne.

Vous compilez avec c90 gcc mais regardez spec c99 :)

2

Non, ce n'est pas un bug. Vous ne pouvez pas utiliser un VLA dans C90. Lorsque vous avez déclaré

const size_t limit 

qui n'est pas une expression constante. Une expression constante serait quelque chose comme une valeur littérale 666.

Notez que C diffère significativement de C++ à cet égard. Même une Comme il est écrit dans votre question constante comme celui-ci

const int i = 666; 

est pas une expression constante C. C'est la raison principale pour laquelle les valeurs constantes sont généralement déclarées avec #define en C.

+0

Merci beaucoup pour votre explication. par curiosité, pourquoi la norme C90 n'accepte pas une expression constante comme celle que je suis tenté d'utiliser? parce que si j'utilise le type const, cela signifie que je ne peux pas le modifier plus tard, alors, quelle est la raison de l'interdire? et C99 std, est autrement, la valeur int ne doit pas être au moins de type const. Désolé pour mon mauvais anglais. :) – Jack

+2

@Jack Vous n'avez pas d'expression constante. Vous avez une variable 'const'. Une expression constante serait 42 ou 66. –

0

, cela est de C99, pas C90, vous devez le compiler avec C99 pour pouvoir utiliser des tableaux de longueur variable.

+1

Vous pouvez également utiliser [alloca] (http://www.kernel.org/doc/man-pages/online/pages/man3/alloca.3.html) à la place. . –

+0

Oui, mais l'allocation dynamique de la mémoire est quelque chose d'autre. – MByD

+0

Est-ce que alloca n'est pas exactement la même chose que l'utilisation d'un tableau de longueur variable? (car il utilise la mémoire de la pile plutôt que le tas) –

3

const n'introduit pas de constante en C mais une variable en lecture seule.

#define SIZE 16 
char bla[SIZE]; // not a variable length array, SIZE is a constant 

mais

const int size 16; 
char bla[size]; // C99 variable length array, size is not constant 
0

Une variable const qualifiée est pas un nombre entier constant expression au sens de la norme. Cela doit être une constante littérale, une constante d'énumération, sizeof ou une expression composée avec ceux-ci.

Passez à C99 si vous le pouvez. L'option gcc est -std=c99 (ou gnu99 si vous voulez l'extension gnu.)

Questions connexes