Utilizando solo las funciones definidas por la norma C (C89, C99 o C11), el único mecanismo de "desactivación" es #undef
.
El problema es que no hay un mecanismo de "volver a habilitar".
Como otros han señalado, si el archivo de cabecera que contiene las definiciones de macro está estructurado de manera que no contiene ningún declaraciones typedef o enum (estos no se pueden repetir; función y declaraciones de variables se pueden repetir), entonces Podría #undef
la macro, hacer lo que necesita sin la macro en efecto, y luego volver a incluir el encabezado, posiblemente después de definir su protección contra la reincorporación.
Si las macros no están definidas en un encabezado, por supuesto, está bloqueado hasta que refactorice el código para que esté en un encabezado.
Otro truco está disponible: si las macros son macros funcionales y no macros similares a objetos.
#define nonsense(a, b) b /\= a
int (nonsense)(int a, int b)
{
return (a > b) ? a : b;
}
La función nonsense()
se define bien, a pesar de la macro inmediatamente antes de ella. Esto se debe a que una macro invocación, para una macro de tipo función, debe ir seguida de un paréntesis abierto (dar o recibir espacio en blanco, posiblemente incluyendo comentarios). En la línea de definición de función, el token después de 'sinsentido' es un paréntesis de cierre, por lo que no es una invocación de la macro nonsense
.
Tenía la macro ha sido un macro-objeto como argumento menos, el truco no funcionaría:
#define nonsense min
int (nonsense)(int a, int b)
{
// Think about it - what is the function really called?
return (a > b) ? a : b;
}
Este código define una función falsa que se llama min
y no tiene sentido. Y no hay protección de la macro.
Esta es una de las razones por las cuales la norma tiene cuidado de definir qué espacios de nombres están reservados para 'La implementación'. La Implementación tiene permiso para definir macros para cualquier propósito que desee o necesite, de cualquier tipo (similar a una función u objeto) que desee o necesite, siempre que esos nombres estén reservados para la implementación. Si usted, como consumidor de los servicios de The Implementation, trata de usar o definir un nombre reservado para la implementación, debe tener en cuenta que su código probablemente se romperá tarde o temprano, y que será culpa suya, no culpa de The Implementation. Implementación.
Supongo que tiene una razón convincente para haber terminado realmente en este macro desastre? No podría pensar en uno aquí ... – sbi