11
votes

Taille des valeurs #define

Si une valeur est définie comme

#define m_40 40

est la taille identique à un court (2 octets) ou est-ce comme un char (1 octet) ou int (4 octets)?

est la taille dépend de la question de savoir si vous êtes 32 bits ou 64 bits?


4 commentaires

Qui dit un court va être 2 octets ou un int va être 4 octets? Ce sont les seules garanties que vous avez: Stackoverflow.com/Questtions/271076/...


@Gman: Bon lien .. Dans mon compilateur et mon environnement, il y a 2 octets afin que j'aurais dû clarifier .. merci


Cette question est étiquetée avec C ++, alors je suppose que c'est ce que vous programmez. Il n'y a aucune bonne raison d'utiliser #define pour ce type de chose en C ++. Il suffit d'écrire const int m_40 = 40; et être fait avec elle. Vous pouvez ensuite modifier le int sur court ou char ou quoi que ce soit que vous aimez si vous vous souciez de la taille. En outre, il manque un peu le point de constantes nommées si le nom de la constante est juste sa valeur. Écriture foo (m_40) n'est pas parfaitement plus clair que foo (40) .


@Tyler: Eh bien, j'ai simplifié le contexte afin que m_40 signifie message 40 dans mon application particulière. Je suis d'accord sur la Constance cependant


5 Réponses :


35
votes

#define n'a pas de taille que ce n'est pas un type, mais une substitution de texte brut dans votre code C ++. #define est une directive prétraiter et il fonctionne avant que votre code commence même à compiler.

La taille dans le code C après substitution est quelle que soit la taille est de ce que C ++ expression ou un code que vous avez là. Par exemple, si vous suffixe avec L comme 102L puis on voit une longue, sinon sans suffixe, juste un int. Donc 4 octets sur x86 et x64 probablement, mais cela dépend compilateur.

Peut-être le C ++ section littéral entier de norme effacer pour vous (section 2.13.1-2 du C ++ 03 standard):

Le type d'un littéral entier dépend sur sa forme, la valeur, et le suffixe. Si ça est décimal et n'a pas de suffixe, il a le premier de ces types dans lesquels sa valeur peut être représentée: int, long int; si la valeur ne peut pas être représentée comme un long int, la comportement est indéfini. Si elle est octal ou hexadécimal et n'a pas de suffixe, il a le premier de ces types dans lesquels sa valeur peut être représentée: int, unsigned int, long int, unsigned long int. Si elle est suffixé par u ou U, son type est le premier de ces types de dont la valeur peut être représentée: unsigned int, unsigned long int. Si ça est le suffixe l ou L, son type est le premier de ces types dans lesquels sa la valeur peut être représentée: long int, unsigned long int. Si elle est suffixé par ul, LU, uL, Lu, Ul, LU, UL, ou LU, son type est unsigned long int


0 commentaires

8
votes

Un entier ordinaire va être implicitement coulé à int dans tous les calculs et affectations.

#define indique simplement au préprocesseur de remplacer toutes les références à un symbole avec quelque chose d'autre. C'est la même chose que de faire une recherche globale à la suite de votre code et de remplacer m_40 avec 40 .


1 commentaires

+1 Global Trouver-remplacement est l'explication la plus rapide et la plus récente



2
votes

une valeur dedefine n'a pas de taille, en particulier. C'est juste une substitution de texte. Cela dépend du contexte de l'endroit où (et de quoi) est substitué.

Dans votre exemple, où vous utilisez M_40 , la compile verra 40 et traitera habituellement c'est comme dans int .

Cependant, si nous avions: xxx

Il sera traité comme longtemps.


6 commentaires

Pas généralement, toujours. Et la constante 40 sera toujours un int dans votre code exemple. Cependant, la valeur 40 sera favorisée à un long lors de l'appel de la fonction. Mais 40 La constante est toujours un int .


@Gman: Pourquoi est-ce toujours un int même si cela pourrait être un simple four 1 octet? Edit (oui je sais que le char n'est pas nécessairement 1 octet)


@Gman: #define L (x) x ## l l (m_40) Maintenant c'est une longue. #define S (x) #x s (m_40) Maintenant c'est un char *, c'est pourquoi j'ai dit "généralement".


@Changeling: C'est à quel point la langue est définie, c'est au § 2.13 / 1 de la norme. Sans suffixe, le type de littéral sera un int ; Si cela ne peut pas aller, ce sera un long int . S'il ne peut pas entrer dans l'une ou l'autre de ceux-ci, le comportement est indéfini. De plus, un char est toujours 1 octet. :) (un octet pourrait ne pas nécessairement être 8 octets, cependant. Généralement, les gens utilisent "Octect" pour faire référence à une collection de 8 octets.)


@Gmam: En outre, la promotion se produit ici à l'heure de la compilation, faisant la différence entre "AT promouvé à un long" et "être [ing] traité comme une longue" une zone très grise.


@James: 40 est un littéral qui a le type int , toujours et pour toujours. Lorsque vous appelez la fonction, le paramètre sera initialisé en tant que long (40) . Dans ce contexte, 40 est toujours un littéral avec le type int . (Et l'ensemble de l'expression donne un long , promu à partir d'une valeur int .) Et en réponse à votre solution de macro alternative, c'est comme: "Est-ce une pomme?" "Oui" " gicle ça non ce n'est pas, c'est le jus de pomme!". Oui 40L n'est plus un INT ... NOR IT IT 40 plus.



1
votes

Le préprocesseur fait simplement une substitution de texte simple, donc le fait que votre constante est dans un #define n'a pas d'importance. Toute la norme C indique que "chaque constante doit avoir un type et la valeur d'une constante doit être dans la plage de valeurs représentables pour son type". C ++ est susceptible de ne pas trop varier de cela.


2 commentaires

Aller plus loin, ce qui fait que C ++ mette la valeur dans un int au lieu de caractère lorsque 40 est une valeur acceptable, par exemple, de type non signé puisqu'il est compris entre 0 et 255?


@Changeling: basé sur les règles standard C ++.



2
votes

Les macros de préprocesseur sont littéralement échangés pendant la phase de préprocession de la compilation.

Par exemple, le code xxx

sera échangé contre xxx

lorsque le compilateur le voit. Il n'a pas de taille propre comme tel


0 commentaires