Quelle est la différence entre un macro et un const en C++?
J'étais posé cette question dans un entretien technique:
Quelle est la différence entre un
const
et une macro en C++?
Ma réponse a été qu'une macro est une directive de préprocesseur et il pourrait être difficile de déboguer l'application si vous utilisez une macro depuis, elle est remplacée par l'expression constante avant la compilation, tandis qu'un const
peut avoir un identificateur de type et est facile à déboguer.
Quelqu'un pourrait-il point une autre différence et qui doit être privilégié?
EDIT:
De la documentation IBM pour le C++:
Voici quelques différences entre
#define
et laconst
type de qualificatif:
La
#define
directive peut être utilisée pour créer un nom pour un numérique, de caractère ou chaîne de caractères constante, tandis qu'un const objet de tout type peuvent être déclarés.Const objet est soumis aux règles de portée pour les variables, tandis qu'une constante créé à l'aide de
#define
ne l'est pas. Contrairement à unconst
objet, la valeur d'une macro n'apparaît pas dans la source intermédiaire de code utilisé par le compilateur car ils sont développés en ligne. La ligne d'extension fait la macro, la valeur indisponible pour le débogueur.Une macro peut être utilisée dans une expression constante, comme un tableau lié, alors qu'un
const
objet ne peut pas. (Je pense que nous avons certainement besoin d'utiliser la macro pour définirarray_size
.Le compilateur n'a pas de type case à une macro, y compris les macro arguments.
OriginalL'auteur Amm Sokun | 2011-06-18
Vous devez vous connecter pour publier un commentaire.
Les Macros et les constantes ne sont pas à distance de la même chose, chacun est parfois appropriées aux circonstances, et votre réponse ne fait qu'effleurer la surface de la différence. Aussi, C++ dispose de deux différents types de constantes.
Une constante définie avec le
const
qualificatif est considéré comme un inmodifiable variable. Il a toutes les propriétés d'une variable: elle a un type, il a une taille, il a de l'assemblage, vous pouvez prendre à son adresse. (Le compilateur peut optimiser certains de ces propriétés si elle peut sortir avec elle: par exemple, les constantes dont l'adresse n'est jamais utilisé ne peut pas obtenir émis dans l'image exécutable. Mais ce n'est que par la grâce du comme-si la règle.) La seule chose que vous ne pouvez pas le faire à unconst
datum est de modifier sa valeur. Une constante définie avecenum
est un peu différent. Il a un type et une taille, mais il n'a pas de lien, vous ne pouvez pas prendre son adresse, et son type est unique. Ces deux sont traités lors de la phase de traduction de l'7, donc ils ne peuvent pas être n'importe quoi, mais une lvalue ou rvalue. (Je suis désolé pour le jargon employé dans la phrase précédente, mais j'aurais à écrire plusieurs paragraphes autrement.)Une macro a beaucoup moins de contraintes: il peut s'étendre à n'importe quelle séquence de jetons, tant que l'ensemble du programme reste bien formée programme. Il n'a pas les propriétés d'une variable. L'application de
sizeof
ou&
à une macro peut ou ne peut pas faire quelque chose d'utile, en fonction de ce que la macro se développe. Les Macros sont parfois définis à l'étendre à de constantes numériques, et ces macros sont parfois la pensée de comme des constantes, mais elles ne sont pas: "le compilateur proprement dit" (c'est la traduction de la phase 7) les considère comme des littéraux numériques.Il est généralement considéré comme une bonne pratique, de nos jours, ne pas utiliser une macro quand un constant va faire. Les Macros ne pas obéir aux mêmes règles de portée que tous les autres identificateurs, qui peut être source de confusion, et si vous utilisez une constante vous donner plus d'informations à la traduction de la phase 7 et donc aussi pour le débogueur. Cependant, les macros vous permettent de faire des choses qui ne peuvent pas être fait de toute autre manière, et si vous avez besoin de faire une de ces choses, vous ne devez pas hésiter à les utiliser. (Macros qui tirent leur poids, dans ce sens, généralement pas étendre à littéraux numériques, bien que je ne vais pas dire jamais.)
EDIT: Voici un exemple de macro de faire quelque chose d'intéressant. Il n'est en aucune manière, la forme ou la forme d'une constante. Il pourrait bien y avoir un moyen d'obtenir le même effet sans une macro (si vous en connaissez un qui n'implique pas de stringstreams, je serais curieux de l'entendre!) mais je pense que cela fait une bonne illustration de la puissance et le danger de macros (pour cette dernière, considérer ce qu'il ferait s'il était utilisé en dehors d'un contexte très spécifique...)
Je ne peux pas penser à un court exemple. Une situation commune, c'est quand vous avez besoin pour assembler un niveau supérieur de construire à partir de nombreux morceaux de texte standard: voir par exemple mxr.mozilla.org/mozilla-central/source/xpcom/glue/... - sans macros ces choses que l'on fait, il y aurait beaucoup plus de risques d'erreurs et fastidieux à écrire. (Je ne souhaite pas tenir jusqu'XPCOM comme un bon exemple, même si, ce que vous voyez est mieux pensé que le tissu cicatriciel sur une conception erronée de la décision rendue il y a longtemps, maintenant réfractaire à corriger.)
Macro de concaténation de chaînes fonctionnalité est très utile lors du débogage #define DEBUG(x) cout<<#x"="<<x; Et son jeton de coller avec fonction ## peut être utilise pour créer de nouveaux identifiants.
Mise à jour de ma réponse avec un exemple de macro qui fait quelque chose de petit mais non négligeable pour obtenir d'une autre manière.
OriginalL'auteur zwol
On doit préférer
const int sum = 1;
sur#define sum 1
pour un certain nombre de raisons:Étendue En Fonction De Mécanisme:
#define
s ne respectent pas les étendues donc il n'y a aucun moyen de créer une classe étendue de l'espace de noms. Tout const variables peut être portée dans les classes.Éviter Bizarre de magique pendant les erreurs de compilation:
Si vous utilisez
#define
ceux-ci sont remplacés par le pré-processeur au moment de la précompilation Donc, si vous recevez une erreur lors de la compilation, il sera source de confusion car le message d'erreur l'habitude de consulter le nom de la macro, mais la valeur et il apparaîtra une soudaine valeur, et l'on perdrait beaucoup de temps de suivi vers le bas dans le code.Facilité de Débogage:
Aussi pour les mêmes raisons, alors que le débogage
#define
apporterait pas aider vraiment.Pour éviter les deux situations ci-dessus
const
sera un meilleur choix.Sokun: Aussi, parce que
macros
sontevil
dans le sens qu'ils produisent toujours des effets secondaires indésirables. Comme pour l'utilisation de macros commenamed constants
en C++ il y a rarement besoin de le faire, à l'Aide de Macros comme l'appelle les constantes vient par l'intermédiaire de C.Je suis venu à travers des numéros de magie, mais de magique doit être vraiment spécial.
OriginalL'auteur Alok Save
Une autre différence est qu'un
const
variable a une mémoire et peut être référencé par un pointeur. Macro est juste le de saisie semi-automatique qui va se passer avant la compilation, d'où le nom est perdu lors de la compilation.Également macro peut être un peu plus qu'une constante. Il peut être suis d'expression ou tout ce qui est syntaxiquement correct, même l'ensemble de définition d'une fonction.
Les Macros sont utilisées pour représenter les choix de programmation par exemple, la taille de la pile; tandis que
cosnt
est utilisée pour décrire le monde réel des constantes comme la valeur de Pi ou e.BOOST_FOREACH
, qui vous permet de vous faire une boucle sur chaque élément dans une séquence dans un endroit propre, de manière concise.OriginalL'auteur Xolve
( Posté pour static const vs #define - reproduire ici cette question semble avoir plus de "momentum"... laissez-moi savoir si c'est inapproprié... )
Des avantages et des inconvénients à tout, en fonction de l'utilisation:
#define
ala#define S std::string("abc")
, mais la constante permet d'éviter que plusieurs de construction de différentes temporaires à chaque point d'utilisation#define X "x"
et parmi ses clients, l'utilisation de l'ala"pre" X "post"
, vous êtes dans le pétrin si vous voulez ou avez besoin de faire X à l'exécution variable variable plutôt qu'une constante, alors que la transition est plus facile à partir d'unconst char*
ouconst std::string
donné qu'ils ont déjà forcer l'utilisateur à intégrer les opérations de concaténation.{ 1, 2 }
qui peut être utilisée pour initialiser des tableaux, ou#define MICROSECONDS *1E-6
etc. (certainement ne la recommande pas!)__FILE__
et__LINE__
peuvent être incorporés dans la substitution macrotemplate <typename T> void f(T t) { cout << ++t; }
ne compile pas)template <typename T> void f(T)
obtenir un distinct lors de l'instanciation passé de la même valeur numérique à partir de différentes énumérations, qui sont distinctes de toute réelle f(int) de l'instanciation.En règle générale, j'utilise consts et d'en tenir compte le plus professionnel option pour utilisation générale (même si les autres sont d'une simplicité séduisante à ce vieux paresseux programmeur).
OriginalL'auteur Tony Delroy
Macros ne respectent pas la portée, et d'une macro nom peut ne pas être disponible pour un débogueur symbolique. Dan Saks a une vue assez complète de l'article sur les mérites relatifs des macros (aucun), objets constants, et de dénombrement des constantes. Comme Stephen Dewhurst, Saks préfère de dénombrement des constantes pour les valeurs entières depuis qu'ils prennent pas de stockage (plus précisément, le dénombrement des constantes ont ni la durée de stockage, ni de liaison).
OriginalL'auteur Gnawme
définir peut être redéfinir , mais const sera la cause d'erreur du compilateur:
de l'échantillon:
source : main.cpp
OriginalL'auteur Phạm Mạnh
Macro comme #define et const deux sont utilisés dans le Langage de Programmation C pour définir des constantes.
Nous allons voir la Différence entre le n ° de définir et de const:
#define
#define
directive est une directive de préprocesseur.#define
ne peut définir simple constante.const
const
est une variable comme une variable normale en langage C.const
pouvez définir des constantes complexes.Pour Compléter La Différence: La différence entre le n ° de définir et de const en C
OriginalL'auteur Shadab Kazi
Une macro de toujours avoir un type, par exemple,
#define FIVE 5
est de type int.Un avantage pour la variable const plus de la macro pourrait être l'utilisation de la mémoire : Avec une macro, la valeur peut être dupliqué partout où il est utilisé une variable const ne sera pas reproduit dans la mémoire. (mais je ne suis pas sûr de cette différence)
5
a un type, maisFIVE
n'a pas de type, parce qu'il disparaisse de l'avant types sont mis en place (phase de traduction du 4 au lieu de 7). Ce n'est pas seulement des règles juridiques: si j'écris#define L_(x) x##L
;#define L(x) L_(x)
; puisL(FIVE)
; le résultat de l'expansion sera5L
, qui a le typelong
.OriginalL'auteur BenjaminB