¿Cuándo debo usar la directiva del procesador #error en un lenguaje C y C ++?

Por lo general, necesita la directiva #error cuando tiene que tomar una decisión en tiempo de compilación basada en macros definidas.

Esta situación a menudo surge en un código multiplataforma.

Permítanme comenzar con un ejemplo práctico. Imagine que su programa debe ejecutarse en Linux y FreeBSD y depende en gran medida de un servicio externo llamado supervisor . FreeBSD y Linux a menudo tienen un enfoque diferente cuando se trata de scripts de inicio. En FreeBSD, su supervisor puede residir en /usr/local/etc/rc.d/ mientras que en Linux puede residir totalmente en /etc/init.d/ .

GCC (junto con algunos otros compiladores) tiene un preprocesador que viene con un conjunto de macros predefinidas. Un buen ejemplo de tales macros sería __linux__ y __FreeBSD__ . Estas macros se establecerán en 1 dependiendo del sistema que ejecute su código. Dado esto, puede escribir el siguiente código para iniciar a su supervisor :

# si está definido (__ FreeBSD__)
const char * const SupervisorStartCmd = “/usr/local/etc/rc.d/supervisor start> / dev / null &”;
const char * const SupervisorStopCmd = “/usr/local/etc/rc.d/supervisor stop”;
#elif definido (__ linux__)
const char * const SupervisorStartCmd = “/etc/init.d/supervisor start> / dev / null”;
const char * const SupervisorStopCmd = “/etc/init.d/supervisor stop”;
#más
#error Define los comandos de inicio / parada para la plataforma.
#endif // __ FreeBSD__
}

Fíjate en la directiva #error . Como sabe cómo iniciar su supervisor solo en Linux y FreeBSD, debe emitir un error de compilación en todas las demás plataformas.

Lo mismo se aplica a otras macros. Si solo es compatible con MIPS y ARM, es posible que desee emitir un #error , cuando un usuario intenta compilar su código en algo como x86.

También puede utilizar la misma técnica para macros definidas por el usuario. GCC tiene una opción -D realmente ingeniosa, que crea una macro con un nombre dado y un valor de 1 . Las lógicas de depuración / liberación a veces pueden depender de dichas macros definidas por el usuario.

Para otros casos de uso vea la respuesta de Swarup Sahoo. Clavó el lado teórico de la pregunta.

Y sí, recuerda que #error suele ser tu última línea de defensa. Las plataformas / compiladores compatibles primero deben ser manejados por su sistema de compilación.

Puede utilizar #error cuando desee detener más compilación de código. Agregue un cheque para la codificación requerida, si no está satisfecho, lance #error. Aquí hay algunos ejemplos:

  • El código es específico de la arquitectura de la plataforma, sistema operativo y versión del sistema operativo, y no desea compilarlo en ninguna otra plataforma.
  • El código es específico del compilador o de la versión del compilador y sabes que la compilación fallará.
  • Cualquier otra condición que pueda ser detectada por el preprocesador y puede usarse para detener la compilación.