То, что вы пытаетесь сделать, не имеет смысла.
#define GLUER(x,y,z) x##y##z
#define PxDIR(x) GLUER(P,x,DIR)
int main() {
int port;
port = 2;
PxDIR(port) |= 0x01;
}
Препроцессор запускается во время (до) компиляции. Поэтому он не может ничего знать о содержимом переменной port
. Препроцессор требует, чтобы все значения, передаваемые в качестве аргументов макросам, были константами. Например, вы можете сделать следующее:
#define GLUER(x,y,z) x##y##z
#define PxDIR(x) GLUER(P,x,DIR)
int main() {
PxDIR(2) |= 0x01; //setup port 2
}
В противном случае, если вы хотите иметь возможность передавать переменную в этот макрос, действительно единственный способ - убедиться, что код для этого генерируется явно:
#define GLUER(x,y,z) x##y##z
#define PxDIR(x) GLUER(P,x,DIR)
uint16_t* get_port_pointer(uint8_t port_id) {
if (port == 0) {
return &PxDIR(0);
} else if (port == 1) {
return &PxDIR(1);
} else if (port == 2) {
return &PxDIR(2);
} else if (port == 3) {
return &PxDIR(3);
} else {
return &0;
}
}
int main() {
int port;
port = 2;
*(get_port_pointer(port)) |= 0x01;
}
Таким образом, мы проверяем, есть ли код для любого порта от 0 до 3, к которому необходимо получить доступ. Кроме того, теперь мы должны следить за тем, чтобы нулевые указатели возвращались из функции get_port_pointer.