664 votes

"static const" vs "#define" en C

Qui est le meilleur à utiliser parmi les déclarations ci-dessous en C?

static const int var=5;

ou

#define var 5

795voto

Jonathan Leffler Points 299946

Cela dépend de ce que vous avez besoin de la valeur. Vous (et tout le monde à ce jour) omis le troisième alternative:

  1. static const int var = 5;
  2. #define var 5
  3. enum { var = 5 };

Ignorant les questions sur le choix du nom, puis:

  • Si vous avez besoin de passer un pointeur autour de vous, vous devez utiliser (1).
  • Depuis (2) est apparemment une option, vous n'avez pas besoin de passer des pointeurs autour.
  • À la fois (1) et (3), un symbole apparaît dans le symbole du débogueur de table qui rend le débogage plus facile. Il est plus probable que (2) n'aura pas un symbole, vous laissant vous demandez-vous ce que c'est.
  • (1) ne peut pas être utilisé comme une dimension pour les tableaux à la portée globale; les deux (2) et (3) peut.
  • (1) ne peut pas être utilisé comme une dimension pour les tableaux statiques à portée de la fonction; les deux (2) et (3) peut.
  • En vertu de C99, tous ces éléments peuvent être utilisés pour les tableaux. Techniquement, en utilisant (1) impliquerait l'utilisation d'un VLA (de longueur variable array), bien que la dimension référencé par 'var' serait, bien entendu, être fixé à la taille 5.
  • (1) ne peut pas être utilisé dans des endroits comme les instructions switch; deux (2) et (3) peut.
  • (2) peut changer le code que vous n'avez pas changé, car il est utilisé par le préprocesseur; à la fois (1) et (3) ne seront pas avoir des effets secondaires inattendus comme ça.
  • Vous pouvez détecter si (2) a été définie dans le préprocesseur; ni (1) ni (3) permet que.

Donc, dans la plupart des contextes, préférez les 'enum' sur les solutions de rechange. Sinon, le premier et le dernier point de la liste de points sont susceptibles d'être des facteurs de contrôle - et vous avez à penser plus si vous avez besoin pour satisfaire les deux à la fois.

Si vous posiez des questions sur C++, vous devez alors utiliser l'option (1) - le static const - à chaque fois.

285voto

Matthieu M. Points 101624

De manière générale:

static const

Parce qu'il respecte la portée et de l'est de type sécurisé.

Le seul inconvénient que je pourrais voir: si vous voulez la variable et pouvant être définies sur la ligne de commande. Il y a toujours une alternative:

#ifdef VAR // Very bad name, not long enough, too general, etc..
  static int const var = VAR;
#else
  static int const var = 5; // default value
#endif

Chaque fois que possible, au lieu de macros / points de suspension, utiliser une solution de rechange sécuritaire.

Si vous avez vraiment BESOIN d'aller avec une macro (par exemple, vous souhaitez __FILE__ ou __LINE__), alors vous feriez mieux de le nom de votre macro TRÈS attentivement: dans sa convention de nommage Stimuler la recommande à tous les majuscules, en commençant par le nom du projet (ici BOOST_), en parcourant la bibliothèque, vous remarquez que ce n'est (en général), suivi du nom de la région en particulier (bibliothèque) puis, avec un nom explicite.

Il fait généralement pour les longs noms :)

113voto

AndreyT Points 139512

En C, en particulier? En C la bonne réponse est: utiliser #define (ou, le cas échéant, enum)

Alors qu'il est bénéfique d'avoir la détermination de la portée et de la frappe des propriétés d'un const objet, en réalité, const objets en C (contrairement à C++) ne sont pas constantes réelles et, par conséquent, sont souvent inutiles dans la plupart des cas pratiques.

Donc, C le choix doit être déterminé par la façon dont vous prévoyez d'utiliser votre constante. Par exemple, vous ne pouvez pas utiliser un const int objet en tant que case label (lorsqu'une macro de travail). Vous ne pouvez pas utiliser un const int objet un peu la largeur de champ (alors qu'une macro de travail). En C89/90 vous ne pouvez pas utiliser un const objet pour spécifier une taille de tableau (lorsqu'une macro de travail). Même en C99 vous ne pouvez pas utiliser un const objet pour spécifier une taille de tableau lorsque vous avez besoin d'un non-VLA tableau.

Si cela est important pour vous, alors il permettra de déterminer votre choix. La plupart du temps, vous n'aurez aucun choix mais pour utiliser #define en C. Et n'oubliez pas une autre alternative, qui produit le véritable constantes en C - enum.

En C++ const des objets sont des constantes réelles, donc en C++, il est presque toujours préférable de préférer l' const variante (pas besoin d'explicite static en C++).

37voto

wrapperm Points 419

La différence entre static const et #define , c'est que le premier utilise la mémoire et la, plus tard, ne pas utiliser de la mémoire pour le stockage. Deuxièmement, vous ne pouvez pas passer l'adresse d'un #define alors que vous pouvez passer l'adresse d'un static const. En fait c'est selon ce que les circonstances nous ne sommes, nous avons besoin de sélectionner l'un d'entre eux deux. Les deux sont à leur meilleur dans des circonstances différentes. Merci de ne pas supposer que l'un est mieux que l'autre... :-)

Si cela aurait été le cas, Dennis Ritchie aurait gardé le meilleur d'un seul... hahaha... :-)

19voto

sellibitze Points 13607

Dans C #define est beaucoup plus populaire. Vous pouvez utiliser ces valeurs pour déclarer la taille des matrices par exemple:

#define MAXLEN 5

void foo(void) {
   int bar[MAXLEN];
}

C ANSI ne vous permettra pas d'utiliser static consts dans ce contexte, autant que je sache. En C++, vous devez éviter les macros dans ces cas. Vous pouvez écrire

const int maxlen = 5;

void foo() {
   int bar[maxlen];
}

et même quitter static car une liaison interne est implicite en const déjà [en C++ seulement].

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:

X