2009-11-30 8 views
17

Tengo un archivo fuente CPP que usa #if/#endif para compilar por completo en ciertas compilaciones. Sin embargo, esto genera la siguiente advertencia.¿Cuál es la mejor manera de eliminar la advertencia de MS Visual C++ Linker: "warning LNK4221"?

warning LNK4221: no public symbols found; archive member will be inaccessible 

Estaba pensando en la creación de una macro para generar una variable ficticia o función que no sería en realidad ser utilizado por lo que este error se iría pero yo quiero para asegurarse de que no causa problemas tales como el uso la macro en múltiples archivos que hace que el enlazador bombardee en símbolos definidos múltiples.

¿Cuál es la mejor manera de deshacerse de esta advertencia (sin simplemente suprimir la advertencia en la línea de comando del enlazador)?

FWIW, estaría interesado en saber cómo hacerlo suprimiendo también la advertencia en la línea de comandos del enlazador, pero parece que el enlazador simplemente ignora todos mis intentos y sigue generando el error.

Otro requisito: la corrección debe ser capaz de resistir construcciones de archivos individuales o compilación unitaria (combinar creaciones de archivos CPP) ya que una de nuestras configuraciones de compilación es una compilación masiva (como una compilación unitaria pero grupos de archivos a granel que un solo archivo maestro de unidad).

+0

¿Qué sintaxis para llamar al enlazador ha intentado (y no funcionó para usted)? –

+0

He intentado "/ ignorar: 4221" para el enlazador y "advertencia #pragma (deshabilitar: 4221)" para el archivo cpp. Ninguno funcionó. – Adisak

+0

Como un aparte, ¿cuál es el propósito de la "construcción unitaria"? –

Respuesta

12

OK, la solución que voy a usar es la sugerencia de Pavel con una pequeña modificación. La razón por la que estoy usando esta revisión es que es una macro fácil de llegar y que funcionará en la mayor-construye/unidad-construye, así como de costumbre construye:

cabecera compartida:

// The following macro "NoEmptyFile()" can be put into a file 
// in order suppress the MS Visual C++ Linker warning 4221 
// 
// warning LNK4221: no public symbols found; archive member will be inaccessible 
// 
// This warning occurs on PC and XBOX when a file compiles out completely 
// has no externally visible symbols which may be dependant on configuration 
// #defines and options. 

#define NoEmptyFile() namespace { char NoEmptyFileDummy##__LINE__; } 

del archivo que pueden compilar por completo:

NoEmptyFile() 
#if DEBUG_OPTION 
     // code 
#endif // DEBUG_OPTION 
20

utilizar un espacio de nombres en el anonimato:

namespace { char dummy; }; 

símbolos dentro de dicho espacio de nombres tienen vinculación externa, por lo que habrá algo en la tabla de exportación. Por otro lado, el nombre del espacio de nombres en sí mismo será distinto (se puede considerar como "generado aleatoriamente") para cada unidad de traducción, por lo que no hay conflictos.

+1

Voy a probar eso. Necesito que funcione con compilaciones unitarias, así que podría tener que convertirlo en una macro con "char dummy ## __ LINE__;" o algo así, así que no tengo símbolos replicados dentro de una sola unidad de traducción. – Adisak

+0

Bueno, no creo que necesites más de uno por unidad. – GManNickG

+0

El arreglo aquí bombardea nuestra construcción unitaria como se esperaba, pero debería funcionar con el mod menor que describí. – Adisak

1

(Aunque la discusión ya está viejo y no puedo comentar directamente la respuesta de @ Adisak), creo que se necesita un poco de magia expansión de la macro adicional para que esto funcione:

#define TOKENPASTE(x, y) x ## y 
#define TOKENPASTE2(x, y) TOKENPASTE(x, y) 
#define NONEMPTY_TRANSLATION_UNIT char TOKENPASTE2(NoEmptyFileDummy, __LINE__); 
Cuestiones relacionadas