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.