Este grupo de trabajo ha pasado mucho tiempo buscando respuestas a tus búsquedas, te ofrecemos la respuesta por eso esperamos serte de mucha ayuda.
Solución:
En MSVC podrías usar push_macro
pragma, GCC lo admite por compatibilidad con los compiladores de Microsoft Windows.
#pragma push_macro("MACRONAME")
#undef MACRONAME
// some actions
#pragma pop_macro("MACRONAME")
Usando solo las facilidades definidas por el Estándar C (C89, C99 o C11), el único mecanismo de ‘deshabilitar’ es #undef
.
El problema es que no hay un mecanismo de ‘rehabilitación’.
Como han señalado otros, si el archivo de encabezado que contiene el macro definiciones está estructurada para que no contenga declaraciones typedef o enum (estas no se pueden repetir; las declaraciones de funciones y variables se pueden repetir), entonces podría #undef
los macrohaz lo que necesites sin el macro en efecto, y luego volver a incluir el encabezado, posiblemente después de anular la definición de su protección contra la reinclusión.
Si las macros no están definidas en un encabezado, por supuesto, está atascado hasta que refactorice el código para que estén en un encabezado.
Hay otro truco disponible: si las macros son macros similares a funciones 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 un macro invocación – para una función similar macro – debe ir seguido inmediatamente de un paréntesis abierto (más o menos espacio en blanco, posiblemente incluyendo comentarios). En la línea de definición de función, el token después de ‘tonterías’ es un paréntesis de cierre, por lo que no es una invocación de la nonsense
macro.
tenía el macro sido un objeto sin argumentos macroel 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 contra el macro.
Esta es una de las razones por las que el estándar tiene cuidado de definir qué espacios de nombres están reservados para ‘La Implementación’. La implementación puede definir macros para cualquier propósito que desee o necesite, de cualquier tipo (similar a una función o similar a un objeto) que desee o necesite, siempre que esos nombres estén reservados para la implementación. Si usted, como consumidor de los servicios de La Implementación, intenta usar o definir un nombre reservado a la implementación, debe tener en cuenta que su código probablemente se romperá tarde o temprano, y que será su culpa, no la culpa de La Implementación. Implementación.
Las macros me debilitan las rodillas, pero la solución más universal no sería reestructurar su código para que no tenga que volver a habilitar el macro de nuevo en el mismo archivo fuente? ¿No sería posible extraer algo de código en una función separada y un archivo fuente separado donde pueda descifrar el infractor? macro.