Puede usar el operador ternario para ce el resultado de la macro a ser un valor de lado derecho, pero el mensaje de error puede ser confuso para los usuarios:
struct node {
node *left, *right;
};
#define LEFT(x) (true ? (x).left : (node*)0)
int main() {
node n;
// LEFT(n); // error
node *l = LEFT(n); // OK
}
El truco no está en la semántica de ese operador específico. El tipo de expresión que contiene solo el operador es un tipo común (o un tipo convertible desde) de las dos ramas de la expresión, incluso si solo una de ellas se evalúa alguna vez. Ahora, cuando el compilador evalúa true ? x.left : (node*)0
, resuelve la expresión x.left
pero con el tipo común de x.left
y (node*)0
. Ambos son básicamente del mismo tipo, con el único detalle de que (node*)0
es un valor r, en lugar de un valor l.
¿Qué hace esa macro? No entiendo por qué alguna vez necesitarías una macro así. – Lundin
@Lundin Lo tomo como ejemplo. para el código real hay muchos miembros con una estructura profunda, las macros de acceso serán útiles. – wsxiaoys
@wsxiaoys Ok, ya veo. Publicaré una respuesta con un ejemplo de cómo debe hacer tales macros. – Lundin