Esta es una parte del código que estoy tratando de entender, pero no puedo entender cómo funciona una macro como esta. La primera línea #define FOREACH_OMPD_STATE(macro) define una macro similar a una función que tiene un parámetro llamado ' macro ', pero ¿qué significa el resto de la definición?
#define FOREACH_OMPD_STATE(macro) \ \ /* first available state */ \ macro (ompt_state_undefined, 0x102) /* undefined thread state */ \ \ /* work states (0..15) */ \ macro (ompt_state_work_serial, 0x000) /* working outside parallel */ \ macro (ompt_state_work_parallel, 0x001) /* working within parallel */ \ macro (ompt_state_work_reduction, 0x002) /* performing a reduction */¿Son esos valores diferentes para el parámetro llamado macro o qué?
FOREACH_OMPD_STATE es una macro X. Proporciona una lista que se usa al pasar varias macros para hacer cosas con los elementos de la lista. Por ejemplo, podemos usar una macro que produce solo los nombres para hacer una lista de identificadores de enum :
#define NameOnly(name, value) name, enum { FOREACH_OMPD_STATE(NameOnly) };Ese código genera (formato de línea agregado para facilitar la lectura):
enum { ompt_state_undefined, ompt_state_work_serial, ompt_state_work_parallel, ompt_state_work_reduction, }; Habiendo hecho eso, podríamos usar una macro diferente que crea inicializadores de matriz para llenar una matriz indexada por los identificadores de enum con los valores proporcionados por la macro FOREACH_OMPD_STATE :
#define MakeInitializer(name, value) [name] = value, int ArrayOfValues[] = { FOREACH_OMPD_STATE(MakeInitializer) };Eso genera (formato de línea agregado para facilitar la lectura):
int ArrayOfValues = { [ompt_state_undefined] = 0x102, [ompt_state_work_serial] = 0x000, [ompt_state_work_parallel] = 0x001, [ompt_state_work_reduction] = 0x002, }; La idea clave es que solo necesitamos enumerar los nombres y valores una vez en el código fuente, al definir la macro FOREACH_OMPD_STATE , y luego podemos usarlos de diversas maneras sin repetirlos.