2010-06-28 10 views
19

Estoy compilando algunos código C++ en MinGW GCC 4.4.0, y obtener advertencias con la siguiente forma ...¿Qué hay de malo con este uso de offsetof?

warning: invalid access to non-static data member '<membername>' of NULL object 
warning: (perhaps the 'offsetof' macro was used incorrectly) 

Este problema parece familiar - algo que he intentado resolver antes y fracasaba, piensa, pero hace un tiempo. El código se compila bien en Visual C++, pero no he construido este código en particular recientemente en ningún otro compilador.

El código de problema es el siguiente plantilla ...

template<typename T> 
class c_Align_Of 
{ 
    private: 
    struct c_Test 
    { 
     char m_Char; 
     T m_Test; 
    }; 
    public: 
    enum { e_Align = offsetof (c_Test, m_Test) }; 
}; 

Obviamente es probable que pueda utilizar algunos compilación condicional para utilizar las funciones específicas del compilador para esto, y creo que C++ 0x voluntad (por fin) hacerlo redundante. Pero en cualquier caso, no puedo ver nada malo con este uso de offsetof.

Muy pedante, es posible que debido a que los T tipos de parámetros son a veces no POD, las clases de manera CCG c_Test como no-POD y se queja (y se queja y se queja - que estoy recibiendo cerca de 800 líneas de estas advertencias) .

Esto es travieso por la terminología estricta de la norma, ya que los tipos que no son POD pueden romper offsetof. Sin embargo, este tipo de no POD no debería ser un problema en la práctica: c_Test no tendrá una tabla virtual, y no se necesita engaño en tiempo de ejecución para encontrar el desplazamiento de m_Test.

Además, incluso si c_Test tiene una tabla virtual, GCC implementa la macro offsetde usando una intrínseca que siempre se evalúa en tiempo de compilación en función del diseño estático de ese tipo particular. Proporcionar una herramienta, luego lloriquear (lo siento, advertir) cada vez que se usa, parece tonto.

Además, yo no soy la única persona por aquí que hace este tipo de cosas ...

Answer to legit-uses-of-offsetof question

que hacen recuerdo haber tenido un problema con offsetof para este tipo de razón, pero Yo no piensa el problema era esta plantilla.

¿Alguna idea?

+0

¿Puede agregar un ejemplo para los tipos de POD que reproducen el problema? –

+0

@Georg - No tiene sentido - No estaba pensando en serio. Tenían constructores y, por lo tanto, no eran POD. Ver la respuesta a continuación. – Steve314

Respuesta

33

Vaya ...

La cuestión es con la estructura c_Test ser no-POD debido al tipo T ser no-POD. He aquí una cita del manual de GCC ...

-Wno-inválida-offsetof (C++ y Objective-C++ solamente)

advertencias Supresión de la aplicación de la 'offsetof' macro a un tipo no-POD .

De acuerdo con la norma ISO C++ de 1998, aplicar 'offsetof' a un tipo no POD no está definido. Sin embargo, en las implementaciones de C++ existentes, 'offsetof' generalmente da resultados significativos incluso cuando se aplica a ciertos tipos de tipos no POD. (Tal como simple 'struct' que no llega a ser un tipo POD sólo en virtud de tener un constructor .) Esta bandera es para los usuarios que son conscientes de que están escribiendo código no portable y que han elegido deliberadamente ignore la advertencia al respecto.

Las restricciones en 'offsetof' pueden ser relajadas en una versión futura del estándar C++ .

Mi problema es que casi todos mis tipos T tienen constructores y, por lo tanto, están clasificados como no POD. Ignoré este punto como irrelevante antes, y por supuesto debería ser irrelevante para la compensación en principio. El problema es que el estándar C++ usa una clasificación POD vs. no POD, aunque hay varias maneras diferentes de no ser POD, y el compilador es correcto para advertir sobre el uso no conforme a los estándares por defecto.

Mi solución por el momento será la opción anterior para suprimir la advertencia; ahora solo necesito averiguar cómo decirle a cmake que la use.

+0

Me siento culpable al aceptar esto. ¿Quizás debería deshacer eso y eliminar la pregunta? – Steve314

+9

Está bien, ya que realmente responde a su pregunta, otros pueden cometer el mismo error. Incluso hay una [insignia] (http://stackoverflow.com/badges/14/self-learner) que fomenta esto :) –

+1

solución cmake: 'conjunto (CMAKE_CXX_FLAGS" $ {CMAKE_CXX_FLAGS} -Wno-invalid-offsetof ") ' – doug65536

-2

Bueno, la interpretación ingenua de este error en particular es tomarlo por su valor nominal: Tiene acceso a un campo privado desde dentro de una enumeración. Pero presumiblemente, las enumeraciones son estáticas por definición (supongo que es por eso que es posible trabajar con constantes enum en primer lugar, son esencialmente constantes int con un nombre elegante).

+0

La enumeración es un miembro de la clase. Los miembros de una clase pueden hacer referencia a miembros privados de la misma clase o, de lo contrario, ¿cómo podrían usar algún miembro privado? No hay ningún problema ocultando datos aquí, pero, bueno, veré mi respuesta (un poco vergonzosa), que debería aparecer en unos minutos ... – Steve314

Cuestiones relacionadas