Pregunta

PC-pelusa Puede informarle sobre los encabezados que están incluidos pero no utilizados.¿Existen otras herramientas que puedan hacer esto, preferiblemente en Linux?

Tenemos una gran base de código que a lo largo de los últimos 15 años ha visto muchas funcionalidades moverse, pero rara vez se eliminan las directivas #include sobrantes cuando la funcionalidad se mueve de un archivo de implementación a otro, dejándonos con un desastre bastante bueno a estas alturas.Obviamente puedo hacer el trabajo minucioso de eliminar todas las directivas #include y dejar que el compilador me diga cuáles volver a incluir, pero prefiero resolver el problema a la inversa (buscar las no utilizadas) en lugar de reconstruir una lista de las usadas.

¿Fue útil?

Solución

RENUNCIA:. Mi trabajo diario está trabajando para una empresa que desarrolla herramientas de análisis estático

Me sorprendería si la mayoría (si no todos) herramientas de análisis estático no tenían algún tipo de verificación Uso de cabecera. Se podría usar esta página Wikipedia para obtener una lista de las herramientas disponibles y enviar por correo electrónico las empresas para pedirles .

Algunos puntos que podría considerar cuando se está evaluando una herramienta:

Para sobrecargas de función, desea que todas las cabeceras que contienen sobrecargas sean visibles, no sólo el encabezado que contiene la función que fue seleccionado por la resolución de sobrecarga:

// f1.h
void foo (char);

// f2.h
void foo (int);


// bar.cc
#include "f1.h"
#include "f2.h"

int main ()
{
  foo (0);  // Calls 'foo(int)' but all functions were in overload set
}

Si se toma el método de fuerza bruta, primero quitar todos los encabezados y luego volver a agregar ellos, hasta que compila, si se agrega primero y luego el código compilará 'f1.h' pero se ha cambiado la semántica del programa.

Una norma similar se aplica cuando se tiene parcial y especializaciones. No importa si se selecciona o no la especialización, es necesario asegurarse de que todas las especialidades son visibles:

// f1.h
template <typename T>
void foo (T);

// f2.h
template <>
void foo (int);

// bar.cc
#include "f1.h"
#include "f2.h"


int main ()
{
  foo (0);  // Calls specialization 'foo<int>(int)'
}

Como para el ejemplo de sobrecarga, el método de fuerza bruta puede resultar en un programa que aún compila pero tiene un comportamiento diferente.

Otro tipo relacionado de análisis que se puede tener en cuenta es comprobar si los tipos se pueden declarar adelante. Considere lo siguiente:

// A.h
class A { };

// foo.h
#include "A.h"
void foo (A const &);

// bar.cc
#include "foo.h"

void bar (A const & a)
{
  foo (a);
}

En el ejemplo anterior, no se requiere la definición de 'A', por lo que el archivo de cabecera 'foo.h' puede ser cambiado de modo que tenga una declaración hacia adelante sólo para 'A':

// foo.h
class A;
void foo (A const &);

Este tipo de control también se reducen las dependencias de cabecera.

Otros consejos

Aquí hay un script que hace que:

#!/bin/bash
# prune include files one at a time, recompile, and put them back if it doesn't compile
# arguments are list of files to check
removeinclude() {
    file=$1
    header=$2
    perl -i -p -e 's+([ \t]*#include[ \t][ \t]*[\"\<]'$2'[\"\>])+//REMOVEINCLUDE $1+' $1
}
replaceinclude() {
   file=$1
   perl -i -p -e 's+//REMOVEINCLUDE ++' $1
}

for file in $*
do
    includes=`grep "^[ \t]*#include" $file | awk '{print $2;}' | sed 's/[\"\<\>]//g'`
    echo $includes
    for i in $includes
    do
        touch $file # just to be sure it recompiles
        removeinclude $file $i
        if make -j10 >/dev/null  2>&1;
        then
            grep -v REMOVEINCLUDE $file > tmp && mv tmp $file
            echo removed $i from $file
        else
            replaceinclude $file
            echo $i was needed in $file
        fi
    done
done

Tener un vistazo a DESHIDRA .

Desde el sitio web:

  

DESHIDRA es un propósito general herramienta ligera, scriptable análisis estático capaz de análisis específicos de la aplicación de código C ++. En el sentido más simple, DESHIDRA puede ser pensado como una herramienta grep semántica.

Debería ser posible para llegar a un script que comprueba si hay archivos # include no utilizados.

cppclean parece que hacer un trabajo decente de la búsqueda de archivos de cabecera no utilizados. Acabo de empezar a usarla. Produce unos pocos falsos positivos. Se encontrará a menudo innecesaria incluye en los archivos de cabecera, pero lo que no le dirá es que se necesita una declaración delante de la clase asociada, y la incluyen necesita ser movido al archivo fuente asociado.

Si está utilizando Eclipse CDT puede intentar Includator que es gratuito para los probadores beta (en el momento de escribir estas líneas) y elimina de forma automática #includes superfluos o añade que faltan.

exención de responsabilidad: yo trabajo para la compañía que desarrolla Includator y han estado usando durante los últimos meses. Funciona bastante bien para mí, así que probarlo: -)

Hasta donde yo sé, no hay ninguno (que no sea PC-Lint), lo cual es una pena y una sorpresa.He visto la sugerencia de hacer este fragmento de pseudocódigo (que básicamente consiste en automatizar su "proceso minucioso":

para cada archivo cpp
para cada encabezado incluir
comenta la inclusión
compilar el archivo cpp
si (compilar_errores)
descomentar el encabezado
demás
eliminar encabezado incluido de cpp

Ponlo en un cron nocturno y debería funcionar, manteniendo el proyecto en cuestión libre de encabezados no utilizados (siempre puedes ejecutarlo manualmente, obviamente, pero llevará mucho tiempo ejecutarlo).El único problema es que no incluir un encabezado no genera un error, pero aún así produce código.

He hecho esto de forma manual y su pena en el corto (Oh, es que a largo plazo - Lleva mucho tiempo?) Plazo debido a la reducción del tiempo de compilación:

  1. Menos cabeceras de analizar para cada archivo CPP.
  2. Menos dependencias - todo el mundo no necesita volver a compilar después de una cambiar a una cabecera.

También es un proceso recursivo - cada archivo de cabecera que se queda en las necesidades que examinan para ver si los archivos de cabecera incluye se puede quitar. Además a veces se puede sustituir declaraciones adelantadas de cabecera incluye.

A continuación, todo el proceso debe repetir cada pocos meses / año para mantener en la parte superior de las cabeceras de sobra.

En realidad, estoy un poco molesto con los compiladores de C ++, que debe ser capaz de decirle lo que no se necesita -. El compilador Microsoft le puede decir cuándo un cambio en un archivo de cabecera puede ser ignorado con seguridad durante la compilación

Si alguien está interesado, sólo putt en sourceforge una pequeña herramienta COMAND línea de Java para hacer exactamente eso. Como está escrito en Java, que es, obviamente, capaz de correr en Linux.

El enlace para el proyecto es https://sourceforge.net/projects/chksem /files/chksem-1.0/

La mayoría de los enfoques para la eliminación sin usar incluye trabajar mejor si primero se asegura de que cada uno de sus ficheros de cabecera compila por su propia cuenta. Hice esto con relativa rapidez de la siguiente manera (disculpas por los errores tipográficos - Estoy escribiendo esto en casa:

find . -name '*.h' -exec makeIncluder.sh {} \;

donde makeIncluder.sh contiene:

#!/bin/sh
echo "#include \"$1\"" > $1.cpp

Para cada ./subdir/classname.h archivo, este enfoque crea un archivo llamado ./subdir/classname.h.cpp que contiene la línea

#include "./subdir/classname.h"

Si su makefile en el. directorio compila todos los archivos cpp y contiene -I., a continuación, sólo volver a compilar pondrá a prueba que cada archivo de inclusión puede compilar por su cuenta. Compilar en su IDE favorito con goto-error y corregir los errores.

Cuando haya terminado, find . -name '*.h.cpp' -exec rm {} \;

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top