Je veux écrire des fonctions / des tableaux de préprocesseur qui sont évalués à
Compiler le temps. Par exemple, si je définis puis, le code p> doit être présenté comme p> au compilateur. (Bien sûr, seuls les littéraux peuvent être utilisés dans l'indice).
Ceci est important si la taille / la mémoire du code est critique et que nous ne voulons pas
Store Les fonctions de compilation de la compilation seraient également bonnes. Par exemple, quelque chose comme p> donc, la déclaration p> doit être présentée au compilateur comme p> Évidemment, nous devons utiliser un littéral comme argument. Est-ce possible? P> p> Myarr code>, mais nous en avons besoin de la commodité de codage. p>
5 Réponses :
myarr pour les caractères que je peux faire toujours réfléchir à des intenses. MyMap est p>
Votre myarr code> serait mieux à faire
(((((((chartons *) "1234567") [x]) code>
@Jens: le const code> ne fait aucune différence. Modifier les littéraux de chaîne est un comportement indéfini afin que le compilateur soit libre de les mettre en stockage constant partagé de toute façon, et dans la pratique, cela le fera.
@R.: Cela fait une différence pour l'appelant. Vous ne pouvez pas accidentellement prendre le résultat comme un lvalue et la modifier. myMap (2) = 27; code> serait autorisé (bien que UB) dans la version d'origine, mais produisez une erreur de compilation avec le
const code>. Je pense que pour les macros comme ça, vous devez être le plus prudent, puisqu'un utilisateur potentiel ne maîtrise de force toutes les conséquences.
Le préprocesseur C standard C ne fera pas ce que vous voulez. Pour obtenir ce type de comportement de manière fiable, vous aurez besoin d'un outil de prétraitement non puissant et non puissant. Cependant, je ne suis pas assez familier avec ce qui est disponible pour vous diriger vers lequel vous voudrez peut-être.
Bien que, dans le second cas, vous pourrez toujours avoir l'effet que vous souhaitez sur la plupart des compilateurs modernes. Par exemple: p> sera toujours présenté au compilateur em> comme: p> mais Le compilateur lui-même, s'il s'agit d'un compilateur moderne raisonnable et que vous lui permettriez d'optimiser, vous remarquerez probablement que cette expression peut être évaluée à la compilée et émettre du code identique à p> Cependant, il n'y a rien que garantit em> qu'un compilateur effectuera cette optimisation. P> P>
Vous pouvez faire des méta-programmations de préprocesseur comme Boost.PP prouve. Son unique encombrant et bien sûr limitée concernant les types de données que vous pouvez travailler.
Il n'y a pas de commandes de préprocesseur standard qui gèrent des tableaux comme vous manquez. Je suggère que vous utilisiez un const. puis pour la question MyMap ... p>
Sûr c'est possible. Bien que vous puissiez le faire manuellement, Boost.preprocessor A > Vous donne déjà les outils dont vous avez besoin: #define MYMAP(x) BOOST_PP_IF(BOOST_PP_EQUAL(x, 1), 5, 2)
pour extraire les composants du pré-dépresseur. P>
@Georg: Dans moderne i> C AKA C99, vous pouvez programmer beaucoup plus simple (et plus facile à lire) que de booster le fait. Boost est limité par le manque de macros variadiques en C ++. Mais avec des littéraux composés, vous l'obtenez même directement, pas besoin d'acrobaties ;-)
@Jens: Bon point - En tant qu'utilisateur principalement C ++, je n'ai pas encore examiné les modèles d'utilisation avec des macros variadiques.
@R ..: Euh, pourquoi? Boost.PP fonctionne de la même manière - préféreriez-vous réexamener toutes les structures de contrôle vous-même?
BOOST.PP n'est pas C. Je donnerais également A -1 pour une recommandation d'écrire un script Perl pour générer un code C, tant que la question était à propos de C et du préprocesseur C.
@R ..: Boost.PP fonctionne avec les préprocesseurs communs que je connais et ne dépend de aucun comportement C ++. Ce qui précède fonctionne avec C et son préprocesseur, donc je ne vois donc pas comment une comparaison avec un script perl convient.
@Georg, wow. Et moi, cependant, le métaprogrammation de modèle était effrayant et que le prétraiteur C n'était pas capable de m'écarter si mal. N'était-ce pas tort. Maintenant, je suis obligé d'en savoir plus sur Boost.PP ...
@RBERTEG, @georg: Pour ceux qui aiment C99 :) J'ai programmé une bibliothèque (les fichiers incluent bien) P99 entièrement basé sur des fonctionnalités de C99. Il n'est pas encore publié mais vous avez peut-être déjà un coup d'œil dans la documentation que j'ai mis en ligne: P99 .gforge.inria.fr / p99-html
@Jens: Nice, semble prometteur. Vous envisagez d'ajouter Enum code>,
Enum_params code>, et al? :)
@Georg: toute sorte de "code déroulant" que vous voulez. Voir par exemple p99.gforge.inria.fr/p99-html/group__statement__lists.html < / a> (Si vous souhaitez discuter de cela, prenons ensuite cette discussion à d'autres canaux.)
Cela s'est avéré être la meilleure solution et oui, il est compatible avec Pure C. Merci! J'ai une question de suivi sur la tentative de sélectionner s'il faut faire un calcul du préprocesseur par rapport au calcul du temps d'exécution. Je suppose que je soutiendrai une nouvelle question.
en C99 (vous avez vraiment besoin de cela, C89 ne ferait pas) que vous pouvez faire quelque chose comme à condition que votre type soit Si ce n'est pas le cas, le compilateur doit créer un objet de réseau quelque part. Avec le J'ai vérifié ceci pour les trois compilateurs que j'ai sur ma machine: < / p> int code>, mais tout autre type ferait. La chose étrange
(int const []) {3, 4, 5, 6, 7} code> est appelée littéral composé. Le
const code> là-bas pour le type de base indique au compilateur qu'il ne sera pas modifié et qu'il peut alias tous ces événements avec le même contenu sur le même emplacement fixe. P>
n code> est une expression qui peut être évaluée à la compilation, telle qu'une valeur fixe
7 < / code> ou
'a' code> ou ainsi. p>
const code>, il pourrait être autorisé à générer une seule copie de celui-ci, quelle que soit la fréquence à laquelle vous appelez la macro dans votre code. Lorsqu'il réussit à le faire, l'initialisation de la matrice serait effectuée à l'heure de la compilation. Il n'y aurait donc aucun moment de compilation. P>
gcc code> et
clang code> allouer le tableau sur
la pile et ceci pour chaque single
Appelez à
MyMap CODE>, Bad em>, puisque la surcharge est proportionnelle à la taille de la matrice. LI>
opencc code> alloue le tableau statique
mais crée une nouvelle copie pour chaque appel
à
myMap code>, meilleur em> mais pas encore idéal. Li>
ul> p>
Si vous souhaitez autoriser l'optimisation du tableau lui-même, vous devez faire attention à ne pas transmettre une variable à la macro.
@CAF: Oui, l'OP a parlé de littéraux i>. Mon hypothèse était qu'il voulait dire compiler des expressions constantes de temps. J'ajoute ça à ma réponse.
+1 Parce que cela s'avère une question beaucoup plus intéressante qu'il ne semblait au premier abord.