2011-09-13 52 views
6

Estoy (estaba) usando las macros __FILE__ y __LINE__ para imprimir mensajes de diagnóstico fuera de mi código. Esto funciona bastante bien cuando utiliza GCC con make, el archivo es tan corto como lo especificó en la línea de comando. Recientemente cambié al uso de CodeLite que utiliza nombres de archivo totalmente calificados (al menos en Windows) al construir. De repente, mi salida de diagnóstico casi no es legible.¿Cómo obtener solo el nombre del archivo en el preprocesador?

¿Hay alguna manera de obtener solo el componente de archivo del nombre de archivo en el preprocesador? Puedo vivir con una solución específica de GCC no portátil. (Me volveré a llamar a __FILE__ otros casos.)

Claro que puedo pasar el contenido de __FILE__ a través de una función y extraer solo el componente de archivo, pero las operaciones de cadena no era lo que tenía en mente para mensajes de diagnóstico que no deberían cambiar comportamiento en tiempo de ejecución ...

NOTA: Utilizo el nombre de archivo de la forma en que GNU lo usa. Una ruta de acceso es una colección de nombres de archivo y un nombre de archivo es un identificador relativo o absoluto de un archivo. Un nombre de archivo puede estar compuesto por un componente de directorio y un componente de archivo.

+0

Los diagnósticos cambian el comportamiento del tiempo de ejecución (de lo contrario no habría diagnósticos) y si llama a una función adicional tiene poca importancia, ya que la salida está llamando a las funciones de la biblioteca para hacer la salida de todos modos. – eudoxos

+0

Imprimir un mensaje de diagnóstico generalmente implica, además de docenas de operaciones de cadena, algunas acciones de E/S de archivo no tan benignas. Por alguna razón, nadie parece estar preocupado por esto. ¿Por qué preocuparse por agregar una llamada a otra función libre de efectos secundarios que solo afecta los mensajes de diagnóstico? –

+0

Ambos tienen razón, agregar diagnósticos no tiene ningún efecto. Lo implementé de esa manera, lo dejé pasar por una función. Me preguntaba más si algo así existe. Seguro que no es estándar, pero encontrar documentación sobre esto no es perfecto. (Incluso el manual de gcc no describe todas las macro predefinidas). – rioki

Respuesta

3

No existe una macro de preprocesador conocida que proporcione la funcionalidad. Pasar __FILE__ a través de una costura de funciones como la única opción sensata.

+0

Para gcc hay [\ _ \ _ BASE_FILE \ _ \ _] (https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html). – fret

+1

@fret: para mí, '__BASE_FILE__' produce el mismo resultado que' __FILE__'. Si lee la documentación a la que se vinculó, proporciona el nombre (no necesariamente el nombre base) del archivo con la función 'main' (no el archivo actual, ni siquiera). – JellicleCat

+1

@JellicleCat tienes razón ... – fret

8

Si está utilizando GNU Make, simplemente puede pasar -D BASE_FILE_NAME = \ "$ *. C \" en la etapa de preprocesamiento de la compilación (si los está haciendo por separado, o en compilación si está en un solo etapa, que es la norma).

Esto depende de la forma en que se determinan los nombres de los archivos. Los míos provienen de una lista de nombres de archivos simples y están prefijados con directorios usando funciones en el archivo MAKE en una etapa posterior.

IE, esto funciona bien para mí, pero su kilometraje puede variar. :-)

Una versión simplificada de mi maquillaje "código":

CLASSES = main.c init.c 

PREPROCESSED = $(patsubst %.c,$(PPCDIR)/%.pp.c,$(CLASSES)) 

$(PREPROCESSED): $(PPCDIR)/%.pp.c: %.c $(ALLH) 
    $(GCC) $(GCCOPTS) -D BASE_FILE_NAME=\"$*\" -E $< > [email protected] 

El simplemente utilizar BASE_FILE_NAME en el código como quiera :-)

+0

Desafortunadamente estoy trabajando con CodeLite, que genera los makefiles para mí. Usar CodeLite es genial, hasta que quieras hacer algo que no cumple con la norma. Todavía agradable ideea, +1 – rioki

+0

La misma idea se puede utilizar en Visual Studio. En Visual Studio 2008: haga clic con el botón derecho en el archivo de proyecto (.vcproj) -> Propiedades -> Propiedades de configuración -> C/C++ -> Preprocesador -> Definiciones de preprocesador. Agregue __BASE_FILE __ = \ "$ (InputFileName) \". Puede usar __BASE_FILE__ en lugar de __FILE__ en sus archivos de origen. – user720594

4

En respuesta a FredCooke anterior, se puede intercambiar esta línea:

-D BASE_FILE_NAME=\"$*.c\" 

Con:

-D BASE_FILE_NAME=\"$(<F)\" 

Esto le dará la expansión adecuada del nombre de archivo, para .cpp también.

Cuestiones relacionadas