¿Cuándo necesitamos #ifdef antes de #undef?


En muchos de los archivos C y C++ he visto macros como esta:

#ifdef X
#undef X  // no statements in between
#endif

Siento que, es adecuado simplemente escribir:

#undef X

Si la macro X no estaba definida, entonces la #undef no debería tener ningún efecto.

Es ok poner standalone #undef, si solo quiero undefine una macro ? ¿Eso hace que la práctica de codificación sea mala de todos modos ?

Author: iammilind, 2012-02-01

3 answers

Véase ISO C99 6.10.3.5, apartado 2.

Una directiva de preprocesamiento del formulario

# undef identifier new-line

Hace que el identificador especificado ya no se defina como un nombre de macro. Se ignora si el identificador especificado no está definido actualmente como un nombre de macro.

Incluso Visual C++ 6 (que era notorio por el mal cumplimiento de los estándares) permite esto:

También puede aplicar la directiva #undef a un identificador que no tenga definición previa. Esto garantiza que el identificador no esté definido. La sustitución de macro no se realiza dentro de las sentencias #undef.

 20
Author: Ken Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-01 04:34:30

Estoy seguro de que es un artefacto de la historia. Como se menciona en la respuesta de jdigital , la 2a edición de K&R dice

No es erróneo aplicar #undef a un identificador desconocido.

Sin embargo, esa frase no está en la edición de 1978. Estoy bastante seguro de que los compiladores pre-estándar a menudo lanzarían un error si intentaras #undef una macro indefinida.

También, la Justificación ANSI C dice :

Se permite explícitamente # undef una macro eso no tiene una definición actual.

Me imagino que si ya fuera una práctica universal, no habría necesidad de mencionarla en la justificación.

Dicho esto, no es necesario en el código moderno, pero en realidad tampoco duele.

 9
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:34

Kernighan y Ritchie (2a edición) están de acuerdo contigo.

EDITAR: cita de la fuente (sección A12. 3):

Una línea de control de la forma

# undef identificador

Hace que la definición del preprocesador del identificador sea olvidada. Si no es erróneo aplicar #undef a un identificador desconocido.

 8
Author: jdigital,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-01 04:27:58