2009-01-22 11 views

Respuesta

23

Esta advertencia aparece cuando tiene una declaración de un tipo que contradice a otra (una dice "clase", la otra dice "estructura"). Dada la regla de una definición, todas las declaraciones excepto a lo sumo uno deben ser declaraciones directas. La advertencia generalmente indicará que una declaración adelantada de un tipo es incorrecta y suele ser un error tipográfico y debe corregirse. En este caso, no debería haber efectos secundarios, pero realmente debería solucionarlo.

Sin embargo, pueden ocurrir algunas cosas muy desagradables si tiene conflictos de nombres de tipos (tal vez causados ​​por el uso de cláusulas de "uso de espacios de nombres" o contaminación del espacio de nombres global). Estas advertencias pueden indicar que está mezclando encabezados de dos bibliotecas diferentes y los nombres de tipo tienen conflictos. El código compilado bajo estas condiciones podría hacer algunas cosas muy inesperadas.

Mi consejo: comprenda por qué ha aparecido la advertencia y fíjelo. Si la advertencia está en un producto de un tercero, insista en que lo solucionen.

+0

Un gran consejo, gracias. –

+2

MS Mangling Scheme en http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling#Data_Type: 'union' se codifica como' T', 'struct' como' U' y 'class' como' V' . –

+0

Gracias! , podría encontrar una estructura typedef ..., causándome esta advertencia. – HadesDX

1

Aunque esto se considera una mala práctica, creo que no debería haber problemas para mezclar definición de clase y declaración de estructura, ya que básicamente son del mismo tipo de datos. La principal diferencia es que los miembros de la estructura son por defecto públicos, a diferencia de los miembros de la clase que son privados, pero por lo demás el diseño de la memoria es idéntico.

+1

Podría ser malo en los compiladores con algoritmos de creación de nombres diferentes. – MSalters

0

En C++ el solo la diferencia entre una clase y una estructura es que los miembros de la clase y las funciones son privadas por defecto, mientras que en una estructura son públicas por defecto; entonces, el hecho de que la clase sea POD no debería hacer ninguna diferencia aquí.
Supongo que esta advertencia proviene del mantenimiento del código (la definición se actualizó en algún lugar pero no en otro lugar) y corrige el código para que desaparezca la advertencia (por ejemplo, usar la clase en typedef).

4

Solo para comentar el comentario de MSalters contra this al nivel superior. He tenido varios errores de enlazador difíciles de encontrar como resultado de que VC usa la palabra clave 'class' o 'struct' en su manipulación de nombres.

¡Si no espera que sea un problema, puede dejarse rascándose la cabeza durante horas!

1

Richard Corden está en lo cierto: hay una razón por la que MS tiene esta advertencia. Los nombres decorados (triturados) incluyen qué clave de clase (struct o clase) es un nombre de tipo. Si una función o método que toma algún objeto como argumento o devuelve ese objeto se referencia en algún lugar cuando la clave de clase incorrecta está visible, no obtendrá un error de compilación pero el enlazador se quejará porque los nombres decorados son diferentes. El error del enlazador solo muestra el símbolo que está buscando, y es fácil pasar por alto la falta de coincidencia de clave de clase allí, por lo que la advertencia del compilador anterior y más detallada es valiosa. Todavía es posible que las dos versiones no aparezcan en la misma unidad de compilación, por supuesto, y es probable que te estés rascando la cabeza por un tiempo si crees que la única diferencia es la visibilidad predeterminada de los miembros.

+0

¿Sigue siendo así en los compiladores de MSVC más recientes? ¿O son 'clase' y' struct' realmente equivalentes para cambiar el nombre ahora? –

2

Discuto esta advertencia en profundidad en mi publicación de blog "Is C4099 really a sillywarning?". Mi conclusión es que es mejor apagarla :-) Bueno, al menos para mí.

1

Una cosa que he visto que puede causar esta advertencia es tratar de importar el archivo .tlb de una DLL y, a la vez, tener la misma DLL como referencia en tu proyecto. Acabo de solucionar un problema al eliminar el archivo DLL como referencia dentro de mi proyecto.

Cuestiones relacionadas