117 votes

Que se passe-t-il si je définis un tableau de taille 0 en C / C ++?

Juste curieux, ce qui se passe réellement si je définir une longueur nulle de la matrice de int array[0]; dans le code? GCC ne se plaint pas du tout.

Exemple De Programme

#include <stdio.h>

int main() {
    int arr[0];
    return 0;
}

Précisions

En fait, je suis en train de voir si le zéro de tableaux de longueur d'initialisation de cette façon, au lieu d'être pointé comme la longueur variable dans Darhazer les commentaires sont optimisés ou non.

C'est parce que j'ai de libérer une partie de code dans la nature, donc je suis en train de voir si je dois gérer les cas où l' SIZE est défini comme 0, ce qui se passe dans certaines parties de code définis de manière statique int array[SIZE];

J'ai été réellement surpris que GCC ne se plaint pas, qui a conduit à ma question. À partir des réponses que j'ai reçues, je crois que l'absence d'un avertissement est due en grande partie à l'appui de l'ancien code qui n'a pas été mis à jour avec le [nouveau] de la syntaxe.

Parce que j'ai été principalement demandais à propos de l'erreur, je suis le marquage Lundin réponse comme correcte (Nawaz s a été le premier, mais il n'était pas aussi complète) -- les autres étaient en soulignant son utilisation effective de la queue-collier de structures, bien que pertinente, n'est-ce pas exactement ce que je cherchais.

79voto

Lundin Points 21616

Un tableau ne peut avoir aucune taille.

ISO 9899: 2011 6.7.6.2:

Si l'expression est une expression constante, sa valeur doit être supérieure à zéro.

Le texte ci-dessus est vrai à la fois pour un tableau simple (§1) et un VLA (§5). Ceci est un texte normatif dans la norme C. Un compilateur n'est pas autorisé à l'implémenter différemment.

gcc -std = c99 -pedantic vous avertit.

74voto

Matthieu M. Points 101624

Normalement, il n'est pas permis.

Toutefois, il est pratique courante en C pour une utilisation flexible des tableaux.

C99 6.7.2.1, §16: Comme un cas particulier, le dernier élément d'une structure avec plus d'un nommé membre peut avoir un incomplètes type de tableau; il s'agit d'un flexible de membre du groupe.

Démonstration:

struct Array {
  size_t _size;
  int content[];
};

L'idée est que vous serait alors répartir ainsi:

void foo(size_t x) {
  Array* array = malloc(sizeof(size_t) + x * sizeof(int));

  array->size = x;
  for (size_t i = 0; i != x; ++i) {
    array->content[i] = 0;
  }
}

Vous pouvez également l'utiliser de manière statique (gcc extension):

Array a = { 3, { 1, 2, 3 } };

Ceci est également connu comme la queue-collier de structures (ce terme est antérieure à la publication du Standard C99) ou struct hack (merci à Joe Wreschnig pour le pointage).

Cependant, cette syntaxe a été standardisé (et les effets de la garantie) n'est que récemment en C99. Avant une taille constante est nécessaire.

  • 1 a été le portable, même si c'était plutôt étrange
  • 0 a été de mieux en indiquant l'intention, mais pas autant que la Norme a été concernés et pris en charge comme une extension par certains compilateurs (y compris gcc)

La queue rembourrage en pratique, cependant, repose sur le fait que le stockage est disponible (attention malloc) est donc pas adapté à l'utilisation des piles en général.

57voto

Nawaz Points 148870

En Standard C et C ++, un tableau de taille zéro n'est pas autorisé.

Si vous utilisez GCC, compilez-le avec l'option -pedantic . Il donnera un avertissement en disant:

zero.c:3:6: warning: ISO C forbids zero-size array 'a' [-pedantic]

Dans le cas de C ++, cela donne un avertissement similaire.

24voto

James Kanze Points 96599

C'est totalement illégal, et l'a toujours été, mais beaucoup de compilateurs négliger de signaler l'erreur. Je ne suis pas sûr de savoir pourquoi vous voulez le faire. La seule utilisation que je connaisse est de déclencher une erreur de compilation à partir d'un booléen:

char someCondition[ condition ];

Si condition est un faux, puis-je obtenir une erreur de compilation. Parce que les compilateurs n'permettre ceci, cependant, j'ai pris à l'aide de:

char someCondition[ 2 * condition - 1 ];

Cela donne une taille de 1 ou de -1, et je n'ai jamais trouvé un compilateur qui accepterait une taille de -1.

8voto

xanatos Points 30513

Je vais ajouter qu'il y a une page entière de la documentation en ligne de gcc sur cet argument.

Quelques citations:

Zéro-longueur tableaux sont autorisés dans GNU C.

Dans la norme ISO C90, vous auriez à donner du contenu à une longueur de 1

et

Versions de GCC 3.0 permis de longueur nulle tableaux être initialisé de manière statique, comme si elles étaient des lanternes. En plus de ces cas qui ont été utiles, il permettait également d'initialisations dans des situations qui pourrait corrompre des données ultérieures

donc, vous pourriez

int arr[0] = { 1 };

et boom :-)

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: