6
votes

Quel est le but de l'opérateur ## en C ++ et que s'appelle-t-il?

Je cherchais à travers le projet Dxutcore fourni avec le SDK DirectX Mars 2009 et remarqua qu'au lieu de faire des méthodes d'accesseur normales, ils ont utilisé des macros pour créer les accesseurs génériques, similaires aux suivants:

#define GET_ACCESSOR( x, y )  inline x Get##y()  { DXUTLock l; return m_state.m_##y;};
...

GET_ACCESSOR( WCHAR*, WindowTitle );


0 commentaires

7 Réponses :


5
votes

C'est un opérateur de prétraitement qui concatéra les opérandes gauche et droit (sans insérer de l'espace). Je ne pense pas que ce soit spécifique Microsoft.


4 commentaires

Ce n'est certainement pas. C Y compris son préprocesseur est plus âgé que MS :)


Je suppose que, mais il est dangereux de poster des choses pour que vous n'ayez pas 100% sûr de ne pas avoir lu la spécification C, je ne pouvais pas savoir avec certitude. ;)


Cependant, l'opérateur de préprocesseur ## n'est pas original C, et bien que ce soit vieux, je ne pense pas que cela ande Microsoft.


Il est standard C. Il est venu à propos car / ** / a fonctionné de cette façon dans les premières versions du prétraiteur C. La norme a décidé qu'un commentaire doit être remplacé par un seul espace qui a nettoyé un boîtier de bord ou deux dans l'analyseur, mais cassé le collier de jeton. Donc, pour compenser, ils ont inventé l'opérateur de collage de jeton et ont jeté dans l'opérateur de stringification pour compenser un autre changement lié au remplacement des jetons à l'intérieur des littéraux de chaîne. Standard C ++ a adopté le préprocesseur C essentiellement intact de sorte qu'il était possible d'analyser une langue sous-ensemble comme C ou C ++.



17
votes

opérateur de colonne de jeton , utilisé par le pré-processeur pour Rejoignez deux jetons en un seul jeton.


0 commentaires

1
votes

C'est la concaténation pour les arguments macro I.e.

inline int GetAge()  { DXUTLock l; return m_state.m_Age;};


0 commentaires

3
votes

8 commentaires

Ceci est standard C ++, voir ma réponse ci-dessous.


Je pense que le point de Randolpho est que C ++ peut l'avoir dans la norme, il pré-dates C ++, c'est-à-dire qu'il s'agit également d'une caractéristique C (météo C ou non).


Ah, je venais de se rapporter à "Ce n'est pas standard C ++", qui n'est pas vrai.


Aussi, comme le goto, dans la programmation «normale», Goto est mauvais, mais il y a des endroits, et si vous faites toujours une programmation «normale» en C, vous avez des problèmes plus importants que les goto. Tester Harnesses Macro est une excellente utilisation en C


@Simeon: Très vrai. Mais vous devriez toujours les éviter pour le code de production. De plus, je suis confus quant aux deux bowvotes que j'ai obtenus sur ce post; Je n'étais en aucune manière inexacte. Peut-être qu'il y a des gens qui aiment les macros et les goto?


Non, je suis sûr qu'ils ont pris la même chose pourquoi je l'ai fait [mais je ne t'ai pas descendu]. Vous avez dit les mots "Ce n'est pas standard C ++", qui est incorrect. Si vous vouliez dire "cela a commencé à C", je suis sûr que vous n'auriez pas eu de bowvotes pour cela, car c'est vrai. En outre, les macro ont leurs utilisations. Ils sont mal et il existe souvent de meilleures façons d'obtenir les mêmes résultats, mais les macro existent toujours parce que sont des cas quand ils sont utiles. Dire que quelque chose devrait jamais être utilisé est tout aussi mauvais que de dire qu'ils devraient toujours être utilisés.


@Gman: vous êtes correct, la phrase "Ce n'est pas standard C ++, il s'agit de la norme C" était censé impliquer que les macros venaient de c et font partie des nombreuses choses gênantes héritées de C ++ de C.. analyser ma réponse et mes commentaires. Je n'ai pas dit "jamais" utiliser des macros. J'ai dit qu'ils sont aussi mauvais que (éventuellement pire que) goto. Vous devez avoir inséré mentalement «jamais». Oui, les macros et le goto ont une place, mais oui, ils devraient être évités à moins que vous ne puissiez pas résoudre un problème sans problème. Même alors, vous devriez être traîné coup de pied et hurler en choisissant de les utiliser.


Je ne vois pas pourquoi ils sont mauvais. L'utilisation de macros est également un signe de mauvaise gestion, et c'est pourquoi je n'utiliserais jamais une langue comme IE. C #.



2
votes

Comme Mehrdad dit, il concaténe les opérandes, comme: xxx

Notez que MISRA C suggère que cet opérande (et le # 'stringify' opérande) devrait ne pas être utilisé en raison de l'ordre de calcul dépendant du compilateur.


0 commentaires

2
votes

Il s'agit d'un opérateur de jeton autorisé par Standard C ++ (voir 16.3.3 pour plus de détails). En ce qui concerne les bonnes pratiques: l'utilisation de la macro n'est pas une bonne pratique IMHO (en C ++).


0 commentaires

6
votes

Ceci est également standard C ++, contrairement à ce que Raldolpho a déclaré.

Voici les informations pertinentes:

16.3.3 L'opérateur ## [CPP.CONCAT]

1 A ## Le jeton de prétraitement ne doit pas se produire au début ou à la fin d'une liste de remplacement pour l'une ou l'autre forme de la définition macro.

2 si, dans le Liste de remplacement, un paramètre est immédiatement précédé ou suivi d'un ## jeton de prétraitement, le paramètre est remplacé par le fichier correspondant Jeton de prétraitement de l'argument Séquence.

3 pour les deux objets - Invocations macro-utiles en forme de fonction, avant que la liste de remplacement soit réexaminé pour plus de noms macro à Remplacer, chaque instance d'un ## Jeton de prétraitement dans le remplacement liste (pas d'un argument) est supprimée et le jeton de prétraitement précédent est concaténé avec ce qui suit jeton de prétraitement. Si le résultat est pas un jeton de prétraitement valide, le le comportement n'est indéfini. La résultante jeton est disponible pour plus de macro remplacement. L'ordre d'évaluation de ## Les opérateurs sont non spécifiés.


0 commentaires