Comment écrire une boucle while avec le préprocesseur C?
Je me suis poser cette question à partir d'un enseignement/piratage de point de vue, (je n'aurais pas vraiment envie de ce type de code).
Est-il possible de mettre en œuvre une boucle while en utilisant uniquement C les directives de préprocesseur. Je comprends que les macros ne peuvent être étendus de manière récursive, alors comment serait-ce possible?
Vous devez vous connecter pour publier un commentaire.
Prendre un coup d'oeil à la Boost de préprocesseur de la bibliothèque, qui vous permet d'écrire des boucles dans le préprocesseur, et beaucoup plus.
Si vous souhaitez mettre en place une boucle while, vous aurez besoin d'utiliser la récursivité dans le préprocesseur. La meilleure façon de faire de la récursivité est d'utiliser un différé d'expression. Un différé d'expression est une expression qui nécessite des analyses plus expansion:
Pourquoi est-ce important? Ainsi lorsqu'une macro est scanné et se développe, il crée une désactivation de contexte. Cette désactivation est le contexte qui va provoquer un jeton, qui fait référence à l'expansion de la macro, pour être peinte en bleu. Ainsi, une fois peint en bleu, la macro va plus s'étendre. C'est pourquoi les macros ne développent pas de manière récursive. Cependant, la désactivation de contexte n'existe que pendant une analyse, par le report d'un agrandissement, nous pouvons empêcher nos macros de devenir peint en bleu. Nous allons juste besoin d'appliquer des analyses plus à l'expression. Nous pouvons le faire à l'aide de cette
EVAL
macro:Ensuite, nous définissons certains opérateurs pour faire un peu de logique(comme si, etc):
Maintenant, avec tous ces macros, nous pouvons écrire un récursif
WHILE
macro. Nous utilisons unWHILE_INDIRECT
macro pour renvoyer à lui-même de manière récursive. Cela empêche la macro d'être peint en bleu, car il s'étendra sur un autre scan(et en utilisant un autre désactivation de contexte). LeWHILE
macro prend un prédicat macro, un opérateur de macro, et un état(ce qui est le variadic arguments). Il maintient l'application de cet opérateur de macro à l'état jusqu'à ce que le prédicat de la macro renvoie la valeur false(0).Pour les besoins de la démonstration, nous allons créer un prédicat qui vérifie si le nombre d'arguments sont de 1:
Ensuite, nous créons un opérateur, ce qui, nous allons juste concat deux jetons. Nous avons également créer un opérateur final(appelé
M
) qui sera le processus de la finale de sortie:Puis à l'aide de la
WHILE
macro:Bien sûr, tout type de prédicat ou l'opérateur peut être transmis.
PRED
comme il est défini en prenantx
et ici:M(EVAL(WHILE(**PRED**, OP, x, y, z))) //Expands to xyz
c'est pas rienm4
xyz
, il l'étend àWHILE ( PRED, OP, xy, z )
, cf. coliru.stacked-crooked.com/a/1a7b4e7879bd7d4bOBSTRUCT(WHILE_INDIRECT)
pasDEFER(WHILE_INDIRECT)
. Voir: coliru.stacked-crooked.com/a/a381ddcbcae0b890Vous utilisez récursive des fichiers à inclure. Malheureusement, vous ne pouvez pas effectuer une itération de la boucle plus que la profondeur maximale que le préprocesseur permet.
Il s'avère que les modèles C++ sont de Turing Complet et peut être utilisé de manière similaire. Découvrez Générative de Programmation
Voici un abus de règles qui permettraient de le faire légalement. Écrivez votre propre C de préprocesseur. Faire interpréter certains #pragma directives sur la façon dont vous le souhaitez.
Je utiliser les méta-modèle de programmation à cette fin, son plaisir une fois que vous obtenez un coup de lui. Et très utile à la fois lorsqu'il est utilisé avec discrétion. Car, comme mentionné son turing, au point où l'on peut même causer le compilateur pour entrer dans une boucle infinie, ou une pile de dépassement de! Il n'y a rien comme aller prendre un café juste pour trouver votre compilation est à l'aide de jusqu'à+ de 30 gigaoctets de mémoire et de tous les CPU pour compiler votre boucle infinie code!
bien, non pas que c'est une boucle while, mais un compteur de boucle, néanmoins la boucle est possible de nettoyer RPC (pas de modèles et pas C++)
J'ai trouvé ce schéma utile lorsque le compilateur suis de mauvaise humeur et ne se déroule pas certaines boucles pour moi
Mais à mon humble avis, si vous avez besoin de quelque chose de beaucoup plus compliqué que cela, alors vous devriez écrire votre propre pré-préprocesseur. Votre pré-préprocesseur peut, par exemple, générer un fichier d'en-tête approprié pour vous, et il est assez facile de comprendre cette étape dans un Makefile pour tout compiler en douceur par une seule commande. Je l'ai fait.
Pas tout à fait ce que vous avez demandé, mais checkout ces liens pour un programme C qui est aussi valable makefile et script shell.
Un gagnant dans les années 2000 obfuscated C concours.
http://www.ioccc.org/2000/tomx.c
http://www.ioccc.org/2000/tomx.hint
By extending this program's idea, It is possible to do some very interesting things like generating C code on execution by adding additional code in make/sh (open up a loop????).
ne sais Pas si c'est ce que l'on entend ou pas...tomx.c
à partir de 2000.