2011-08-09 14 views
8

Pensé que los métodos private, que no se usan dentro de su clase, son eliminados por el compilador/enlazador y no serían parte del binario final.¿Cómo excluir los métodos no utilizados del binario final?

He creado una clase de ejemplo, con un método privado que se implementa pero no se utiliza.

class XXX 
{ 
    public: 
    XXX(); 

    private: 
    void MyUnusedMethod(); 
}; 

Y en el archivo de implementación:

void XXX::MyUnusedMethod() 
{ 
    const char* hugo = "ABCCHARLYABC"; 
    printf(hugo); 
} 

Después de la compilación todavía existen la cadena en el binario final. ¿Por qué? ¿Y cómo puedo evitar esto?

Saludos, Charly

+0

¿Por qué no puedes poner ese método en el bloque '#if 0 ... # endif'? – iammilind

+0

¿Ha intentado ajustar los indicadores de optimización para gcc? – slaphappy

+0

Si te refieres al indicador '-O3', no hace ninguna diferencia. Por supuesto, si sé que no lo usaré más, no soy demasiado perezoso para eliminarlo. Pero también es una pregunta general: ¿por qué no se elimina por el compilador/vinculador? – Charly

Respuesta

7

Una forma portátil es tener un archivo .o para cada función. Luego crea un archivo .a a partir de esos archivos .o. Al vincular con ese archivo, el vinculador vincula solo aquellos archivos .o que resuelven símbolos, es decir, los archivos .o con una función a la que nadie llama no están vinculados.

Otra forma es utilizar las últimas versiones de gcc con link-time code generation.

+1

+1 para la generación de código de tiempo de enlace, ¡que parece ser la solución ideal para mí! – Veger

1

Esta es probablemente una mala idea, pero tengo que escribir de todos modos :) Se puede crear una clase de plantilla, los métodos utilizados AFAIR se eliminan.

+0

eh? ¿De Verdad? afaik, cualquier instancia tendrá todo el código. – Nim

+0

Tengo que comprobar que para estar realmente seguro, pensé que lo había leído en alguna parte. No tengo el libro de plantillas a mano ahora:/ – duedl0r

+0

La respuesta es correcta.El razonamiento es que 'clase Foo ' puede ser útil incluso si no todos los métodos se compilan para todos los valores de 'T'. P.ej. 'T == const int' podría romper todos los métodos no const de' Foo '. – MSalters

3

Después de la compilación, la cadena todavía existe en el binario final. ¿Por qué

Otros han dado sugerencias sobre cómo deshacerse de ese código no utilizado en el binario final. Me gustaría dar un poco de respuesta en el Why - aquí hay dos puntos por los que podría ser imposible eliminar la función.

A menos que usted declaró todos los objetos de ese tipo con XXXstatic linkage, el compilador no puede pelar el tipo (y por lo tanto el método) desde el archivo objeto generado debido a algún otro archivo objeto podría acceder el valor con extern. El enlazador, que puede ver todos los archivos de objetos a la vez, podría resolverlo.

Sin embargo, como etiquetó su pregunta como gcc, es posible que no esté compilando y/o vinculando con -fvisibility=hidden. En ese caso, incluso el vinculador no puede quitar el símbolo (y, por lo tanto, el código) porque otros módulos pueden resolver el símbolo en tiempo de ejecución.

+0

"(y de ahí el método)" no se desprende de la premisa. Sin importar la cantidad de objetos, si no hay ninguna llamada para 'MyUnusedMethod', entonces no necesita estar en el binario. – MSalters

+0

@MSalters: si el símbolo de 'MyUnusedMethod' no se elimina en el módulo final (por ejemplo, ejecutable de biblioteca compartida), es posible que algún otro módulo se resuelva y acceda al símbolo en tiempo de ejecución. Es muy común que el código que no se utiliza dentro de un módulo permanezca en el módulo, piense en las funciones expuestas por una biblioteca compartida. –

7

Esto generalmente se hace pasando -funciones-secciones -fdata-secciones opciones para gcc. Mira esto link para más detalles.

Cuestiones relacionadas