web-dev-qa-db-fra.com

#define instructions dans un espace de noms

Si j'ai une instruction #define dans un espace de noms en tant que tel:

namespace MyNamespace
{
  #define SOME_VALUE 0xDEADBABE
}

Ai-je raison de dire que l'instruction #define n'est pas limitée à l'espace de noms? 

La chose suivante est-elle la "bonne" chose à faire?

namespace MyNamespace
{
  const unsigned int SOME_VALUE = 0xDEADBABE;
}
47
Soo Wei Tan

Correct, #define 's ne sont pas liés par des espaces de noms. #define est une directive préprocesseur - qui entraîne la manipulation du fichier source avant sa compilation par le compilateur. Les espaces de noms sont utilisés lors de la compilation et le compilateur n'a aucune idée des #define.

Vous devriez essayer d'éviter le préprocesseur autant que possible. Pour des valeurs constantes comme celle-ci, préférez const à #define.

60
Michael

Je suis tout à fait d’accord avec les suggestions concernant l’utilisation de constantes et la portée illimitée de #defines.

Cependant, si vous faire utiliser des lignes de pré-traitement #define, couvrez-les correctement pour la portée attendue,

namespace MyNamespace
{
  #define SOME_VALUE 0xDEADBABE
  // your code
  #undef SOME_VALUE
}

Pourquoi #defines?
Je connais un cas où une plate-forme intégrée ne prend pas en charge les constantes dans le code.
Il n'y avait aucun moyen de les initialiser ...
Cela aide toujours à être plus lisible.

19
nik

Le préprocesseur opère (conceptuellement au moins et souvent en fait aussi) avant les espaces de noms et autres concepts de niveau de langage "entrent en jeu" - alors oui, il est certainement beaucoup préférable d'utiliser des constructions de niveau de langage telles const valeurs partout où vous le pouvez!

4
Alex Martelli

Oui. En général, utiliser des valeurs const au lieu de # valeurs définies a de nombreux avantages. Limiter la portée de la variable est l’un des avantages. La portée peut être restreinte à un espace de noms ou à une autre portée valide de cette manière (y compris au niveau classe, fonction, etc.).

3
Reed Copsey

Si, pour une raison quelconque, vous ne pouviez pas passer au second cas, je suis presque certain que vous devrez veiller à compiler MyNamespace dans son propre objet et à lier les objets séparément (ou éventuellement simplement exécuter le préprocesseur sur cet espace de nom par lui-même). Le préprocesseur C++ doit utiliser cette instruction #define et effectuer essentiellement une chaîne de remplacement n'importe où que SOME_VALUE apparaît dans le code source. Par conséquent, si le préprocesseur n'a pas connaissance du #define, SOME_VALUE ne peut pas être remplacé dans un autre fichier source.

0
Mark Rushakoff