2011-10-24 7 views
5

Tengo este código muy simple;Comportamiento diferente entre estándar deque/vector en MSVCC/g ++/icc

#include <deque> 
#include <vector> 

using namespace std; 

class A 
{ 
public: 
    A(){}; 
    ~A(){}; 
    deque<A> my_array; // vector<A> my_array; 
}; 

int main(void) 
{ 
} 

Si puedo compilar el código tanto con g ++ y CPI/ICPC en Linux se compila bien, incluso con -Wall da ninguna advertencia. Si cambio el deque a un vector, la situación es la misma.

me gustaría construir este código en Windows utilizando MSVCC (cl) pero por desgracia lanza C2027 de error:

error C2027: use of undefined type 'A' 

Sin embargo, si se cambia el std::deque a un std::vector que compila bien con Visual Studio 2010.

Mi pregunta es; ¿es este comportamiento esperado por alguna razón? Si es así, ¿por qué hay diferencias entre compiladores o es un error con g ++/icc o MSVCC?

Respuesta

12

Es un comportamiento indefinido (ambos con std::deque y con std::vector, así que lo que una implementación hace con ella está bien, en lo que se refiere a la norma . Estas instancias de un contenedor estándar con un tipo incompleto.

Cuando se compila con g ++, -Wall (y en general, todas las opciones empezando con -W) sólo afectan a la lengua. Por cuestiones de biblioteca, debe ser compilar con -D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC también. (Si esto causa rendimiento problemas, puede quitar la última t wo -D en compilaciones optimizadas.)

+0

+1, sin embargo, esperaba ser un UB con 'deque' solamente. – iammilind

+0

"lo que hace una implementación con él está bien, en lo que respecta al estándar" - una implementación conforme no debe dejar de compilarlo solo porque tiene un comportamiento indefinido. Aunque, por supuesto, puede proporcionar diagnósticos y poner una implementación en un modo conforme donde esos diagnósticos son solo advertencias puede ser un poco oscuro. –

+0

@SteveJessop La definición de _undefined behavior_ en la norma (§1.3.12) dice explícitamente "para lo cual esta Norma Internacional impone ** no ** requirements" (emphisis agregado). Y en la nota inmediatamente siguiente , da "[...] terminar una ** traducción ** o ejecución (con la emisión de un mensaje de diagnóstico)" como un ejemplo de lo que podría hacer una implementación . –

0

Además de la respuesta de James Kanze, busqué y encontré this Dr Dobbs article, lo que explica la postura de la norma sobre el uso de contenedores con tipos incompletos.

Además, insinúa que la razón por la que funciona con vector s, pero no deque s, es decir, la implementación. Un vector típico puede ser algo como

class vector<T> { 
    T* buff; 
    int size; 
    // ... snip 
}; 

que es bien con tipos imcomplete ya que sólo tenemos un puntero a T pero deque bien podrían implementarse de tal manera (en VS2010) que hace uso de T por valor lo que lo hace incompatible con tipos incompletos.

Cuestiones relacionadas