what va_args macro define c string concatenation c-preprocessor

va_args - gcc macros



Stringification de un valor de macro (3)

Enfrenté un problema: necesito usar un valor de macro como cadena y como número entero.

#define RECORDS_PER_PAGE 10 /*... */ #define REQUEST_RECORDS / "SELECT Fields FROM Table WHERE Conditions" / " OFFSET %d * " #RECORDS_PER_PAGE / " LIMIT " #RECORDS_PER_PAGE ";" char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; /* ...and some more uses of RECORDS_PER_PAGE, elsewhere... */

Esto falla con un mensaje sobre "parásito #", e incluso si funcionó, supongo que obtendría los nombres de las macros codificadas, no los valores. Por supuesto, puedo enviar los valores al método final ( "LIMIT %d ", page*RECORDS_PER_PAGE ) pero no es bonito ni eficiente. Es en momentos como este cuando deseo que el preprocesador no trate las cadenas de una manera especial y procese su contenido como el código normal. Por ahora, lo compaginé con #define RECORDS_PER_PAGE_TXT "10" pero comprensiblemente, no estoy contento con eso.

¿Cómo hacerlo bien?


Intenta escaparte dos veces de tus citas

#define RECORDS_PER_PAGE 10 #define MAX_RECORD_LEN 10 /*... */ #define DOUBLEESCAPE(a) #a #define ESCAPEQUOTE(a) DOUBLEESCAPE(a) #define REQUEST_RECORDS / "SELECT Fields FROM Table WHERE Conditions" / " OFFSET %d * " ESCAPEQUOTE(RECORDS_PER_PAGE) / " LIMIT " ESCAPEQUOTE(RECORDS_PER_PAGE) ";" char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; int main(){ char * a = REQUEST_RECORDS; }

compila para mi El token RECORDS_PER_PAGE se expandirá mediante la ESCAPEQUOTE macro ESCAPEQUOTE , que luego se enviará a DOUBLEESCAPE para que se DOUBLEESCAPE .


La macro xstr definida a continuación se stringify después de hacer macro-expansión.

#define xstr(a) str(a) #define str(a) #a #define RECORDS_PER_PAGE 10 #define REQUEST_RECORDS / "SELECT Fields FROM Table WHERE Conditions" / " OFFSET %d * " xstr(RECORDS_PER_PAGE) / " LIMIT " xstr(RECORDS_PER_PAGE) ";"


#include <stdio.h> #define RECORDS_PER_PAGE 10 #define TEXTIFY(A) #A #define _REQUEST_RECORDS(OFFSET, LIMIT) / "SELECT Fields FROM Table WHERE Conditions" / " OFFSET %d * " TEXTIFY(OFFSET) / " LIMIT " TEXTIFY(LIMIT) ";" #define REQUEST_RECORDS _REQUEST_RECORDS(RECORDS_PER_PAGE, RECORDS_PER_PAGE) int main() { printf("%s/n", REQUEST_RECORDS); return 0; }

Productos:

SELECT Fields FROM Table WHERE Conditions OFFSET %d * 10 LIMIT 10;

Tenga en cuenta la indirección a _REQUEST_RECORDS para evaluar los argumentos antes de stringifying ellos.