Estoy haciendo esta pregunta a partir de enseñanza y/o la piratería punto de vista, (no realmente quiero a un código como este).
Es posible implementar un bucle while utilizando sólo C las directivas de preprocesador. Entiendo que las macros no se puede ampliar de forma recursiva, de modo que ¿cómo podría lograrse esto?
Echar un vistazo a la Impulsar el preprocesador de la biblioteca, que permite escribir bucles en el preprocesador, y mucho más.
Si quieres implementar un bucle while, usted tendrá que utilizar la recursividad en el preprocesador. La manera más fácil de hacer la recursividad es el uso de un aplazamiento de expresión. Un aplazamiento de expresión es una expresión que requiere más análisis para que se expanda:
¿Por qué es esto importante? Así cuando una macro es escaneada y en expansión, crea una desactivación de contexto. Este incapacitante contexto provocará un token, que se refiere a la actualidad, la expansión de la macro, para ser pintado de azul. Por lo tanto, una vez que está pintado de azul, la macro ya no se puede expandir. Esto es por qué las macros no se expanden de forma recursiva. Sin embargo, la desactivación de un contexto sólo existe durante un análisis, por lo que mediante el aplazamiento de una expansión podemos evitar que nuestras macros de convertirse pintado de azul. Nosotros sólo tendrá que aplicar más análisis para la expresión. Podemos hacer que el uso de este
EVAL
macro:A continuación, vamos a definir algunos de los operadores para hacer algo de lógica(como si, etc):
Ahora con todas estas macros se puede escribir una recursiva
WHILE
macro. Utilizamos unWHILE_INDIRECT
macro para referirse a sí mismo de forma recursiva. Esto evita que la macro de ser pintada de azul, ya que se expanda en una exploración diferentes(y usando un tipo diferente de desactivación de contexto). ElWHILE
macro toma un predicado macro, un operador de la macro, y un estado(que es el variadic argumentos). Se mantiene la aplicación de este operador macro para el estado hasta que el predicado de la macro devuelve false(0).Para fines de demostración, sólo se va a crear un predicado que comprueba cuando el número de argumentos son la 1:
A continuación creamos un operador, que le concat dos testigos. También creamos un operador final(llamado
M
) que el proceso de la producción final:A continuación, utilizando el
WHILE
macro:Por supuesto, cualquier tipo de predicado o el operador puede ser transmitido.
PRED
como es definido por tomarx
y aquí:M(EVAL(WHILE(**PRED**, OP, x, y, z))) //Expands to xyz
es no tomar nadam4
xyz
, que se expande aWHILE ( PRED, OP, xy, z )
, cf. coliru.stacked-crooked.com/a/1a7b4e7879bd7d4bOBSTRUCT(WHILE_INDIRECT)
noDEFER(WHILE_INDIRECT)
. Ver: coliru.stacked-crooked.com/a/a381ddcbcae0b890Utilizar recursiva incluir archivos. Desafortunadamente, no se puede recorrer en iteración del bucle más que la profundidad máxima a la que el preprocesador permite.
Resulta que las plantillas de C++ son Turing Completo y puede ser utilizado de manera similar. Echa un vistazo Generativo de Programación
Aquí hay un abuso de las reglas que hacerlo legalmente. Escribir su propio preprocesador de C. Hacen interpretar algunos #pragma directivas de la manera que usted desea.
Yo uso el meta-modelo de programación para este propósito, es divertido una vez que usted consigue un bloqueo de la misma. Y muy útil cuando se utiliza con discreción. Ya que como se menciona su turing completo, hasta el punto donde usted puede incluso hacer que el compilador de entrar en un bucle infinito, o la pila de desbordamiento! No hay nada como ir a tomar un café sólo para encontrar su compilación es el uso de hasta 30+ gigabytes de memoria y la CPU para compilar el bucle infinito de código!
bueno, no es que sea un bucle while, pero un contador de bucle, sin embargo, el bucle es posible en limpio CPP (no plantillas y no C++)
He encontrado este esquema útil cuando el compilador tengo mal humor y no se desenrolle ciertos bucles para mí
Pero en mi humilde opinión, si necesitas algo mucho más complicado que eso, entonces usted debe escribir su propio pre-preprocesador. Su pre-preprocesador podría, por ejemplo, generar un archivo de encabezado apropiados para usted, y es bastante fácil de incluir este paso en un archivo Makefile para tener todo compilar sin problemas mediante un único comando. Yo lo he hecho.
No es exactamente lo que usted pidió, pero checkout estos enlaces a un programa en C que también es válido makefile y shell script.
Un ganador en el 2000 ofuscado C concurso.
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????).
No estoy seguro si esto es lo que se entiende o no…tomx.c
de 2000.