2012-03-09 12 views
9

Mi biblioteca C tiene algunas características opcionales, y al utilizar automake, el usuario puede activarlas y desactivarlas mediante la configuración de indicadores.¿se considera una buena práctica tener condicionales en archivos de encabezado públicos?

Si se desactiva una función, esa función no se compilará.

Sin embargo, mi pregunta es, ¿debería eliminar también el prototipo de función de los encabezados públicos en ese caso?

Parece que no es una buena idea tener prototipos de función para funciones que no están compiladas, pero también no me parece una buena idea tener diferentes cabeceras públicas instaladas dependiendo de la configuración de la biblioteca. (Similar a cómo es mala práctica instalar config.h en el directorio de encabezados públicos.)

¿Cuál es el mejor enfoque para los encabezados públicos cuando se trata de características opcionales? Si un usuario intenta usar una función deshabilitada, ¿debería aparecer el error en tiempo de compilación o tiempo de enlace? Debe haber una práctica estándar para esta situación. (Yo prefiero para cumplir con los estándares de codificación de GNU si hay varias ideas, pero no sé de la norma GNU sobre este tema.)

+1

I creo que es un buen yo dea no incluir el prototipo si la función no está definida, de modo que el error se encuentre en tiempo de compilación en lugar de tiempo de enlace, pero no conozco ninguna práctica estándar sobre esto. Yo usaría #if. –

+0

@VaughnCato si el prototipo está excluido por una directiva de preprocesador, obtendrá un error de compilación. –

+0

@LuchianGrigore sí, exactamente. –

Respuesta

1

Creo que hay 2 enfoques válidos a este problema

  • tener un archivo de cabecera única que utiliza #ifdef para eliminar funciones que no son compatibles en ciertas configuraciones
  • tener varios archivos de cabecera sin #ifdef cada uno de los cuales es específico para una configuración

parece lik Es realmente una mala práctica dejar funciones que no están presentes en la lib en el archivo de encabezado para una configuración dada. Tomará lo que debería ser un error de tiempo de compilación y lo moverá a un enlazador.

+1

No me gusta la segunda sugerencia, accidentalmente puede incluir los archivos manualmente. –

+0

@LuchianGrigore Estoy de acuerdo en que no es mi preferencia. Lo considero un paso más arriba de tenerlos a todos en un solo archivo aunque sin '# ifdefs' – JaredPar

3

Definitivamente no solo excluye la implementación de la compilación, sino toda la función.

//feature.h 
#ifndef EXCLUDE_FEATURE 
    void foo(); 
#endif 

//feature.c 
#include "feature.h" 
#ifndef EXCLUDE_FEATURE 
void foo() 
{ 
} 
#endif 

De esta manera, obtendrá un compilador, no ligador error, si intenta utilizar foo con la característica excluida. Desea señalar un error lo antes posible, los errores del enlazador en general transmiten menos acerca de la intención del desarrollador.

Microsoft hace esto (condicionales en archivos de encabezado) para MFC y funciona muy bien. . (Por supuesto que es C++, pero las gradas principales

+1

Bien, gracias. Pensé en eso, mi única preocupación es que me parece muy similar incluir el archivo config.h, por ejemplo: tenía la impresión de que la configuración específica de la biblioteca no debería reflejarse necesariamente en los encabezados, como p. Ej. Se pueden instalar múltiples versiones de la biblioteca. Esa es realmente mi única preocupación con este enfoque. – Steve

1

observé el siguiente enfoque en algunos proyectos:. Generar el archivo de cabecera de una plantilla de un

La generación de archivos se basa en las banderas de configuración

.

Este enfoque me parecía más limpio que el uso de interminables definiciones condicionales en la cabecera ... me parece mucho más limpio

Desventaja:.. puede ser una carga de soporte (por el guión)

Cuestiones relacionadas