Desdefiniendo el pre-procesador C ++

Solo hay dos tipos de idiomas: aquellos de los que la gente se queja y los que nadie usa – Bjarne Stroustrup

Me gusta esa cita. explica tanto JavaScript como Haskell. Y según esa medida, el preprocesador es un gran lenguaje porque la gente lo usa mucho. Nunca se considera por separado de C y C ++, pero si lo fuera, sería el idioma número uno en TIOBE . El preprocesador es extremadamente útil y omnipresente. La verdad es que sería * realmente * difícil de escribir cualquier tipo de aplicación de C ++ seria y portátil sin que el preprocesador estuviera involucrado en algún momento.

– El preprocesador es una mierda

– ¿Yo se, verdad? Esto es lo peor. Oye, ¿puedes fusionar mi compromiso? Agregué un montón de macros útiles.

Creo que muchas personas están familiarizadas con ese tipo de conversación, y si no tenemos cuidado, es posible que aún las tengamos dentro de 20 años. Porque la existencia es, desafortunadamente, la única cualidad redentora del preprocesador. Por desgracia, mis problemas no son teóricos, filosóficos ni idealistas.

No me importa en absoluto que el preprocesador permita a nadie reemplazar identificadores, palabras clave (algunos dicen que eso es ilegal, en la práctica …) sin ningún tipo de control. Tampoco me importa que el preprocesador se convierta en Turing completo sin poder manejar las comas correctamente. Ni siquiera me importa incluir e incluir guardias, y no tengo un solo problema con #pragma . A veces tienes que ser pragmático.

Sin embargo.

Déjame ofrecerte un escenario, puede que te resulte artificial, pero por favor ten paciencia conmigo. Imagine que está refaccionando una aplicación multiplataforma y decide hacer algo inusual como, por ejemplo, cambiarle el nombre a una función.

Eso no es posible. Nunca lo he sido, probablemente nunca lo será.

Renombrar foo – un problema sin solución para el cual no hay un premio del Milenio

Fundamentalmente, ni el compilador ni sus herramientas (una herramienta que es necesariamente un front-end de compilador completo) tienen una vista completa de su código. Las partes deshabilitadas no son compiladas, analizadas, léxicas o analizadas de otro modo.

Primero, las rutas deshabilitadas no tienen obligación de ser válidas C ++. Esto es válido:

La mejor forma de distribuir tu aplicación C ++.

Entonces, si el compilador tuviera en cuenta las rutas deshabilitadas del preprocesador, es posible que no pueda realizar una AST válida. Peor aún, el preprocesamiento, como su nombre indica, sucede como un estado separado y una directiva de preprocesamiento puede insertarse entre dos tokens de C ++, incluido en el medio de cualquier expresión o enunciado.

Algunas de estas ramas pueden formar una declaración de C ++ válida.

El otro tema igualmente preocupante es que el compilador posiblemente no puede saber qué combinación de #ifdef y #defines se supone que forman un programa válido.

Como ejemplo, Qt ofrece un conjunto de defines que se pueden configurar para habilitar o deshabilitar ciertas características de Qt en tiempo de compilación. Supongamos que no necesita un widget de calendario, puede definir #QT_NO_CALENDAR_WIDGET y eso lo convierte en un binario más pequeño. No funciona Sospecho que nunca funcionó. Ver, en algún momento, Qt tenía unas 100 opciones de configuración de tiempo de compilación. Dado que el número de configuraciones de construcción posibles explota exponencialmente con el número de variables. cuando puede tener una variación de 2¹?? de su programa, la automatización resulta difícil, incluso a escala de la gran web profunda.

El código no probado es código roto.

Probablemente conozcas ese famoso adagio. Entonces, ¿qué pasa si ni siquiera compilamos el código?

Debo señalar que poner algún método específico de la plataforma en archivos específicos de la plataforma conduce exactamente al mismo problema. Básicamente, el código que ve el compilador debe ser una única fuente de verdad autónoma, pero en cambio el código está fragmentado y la visión que usted tiene de él es, como mejor, incompleto.

Texto original en inglés.