Uso de clase incompleta en la plantilla

Estoy muy sorprendido de que en varias versiones muestreadas de g ++, las siguientes compilaciones sin error o advertencia:

// Adapted from boost::checked_delete()
template <class T> inline void assert_complete()
{
  typedef char type_must_be_complete[ sizeof(T) ? 1 : -1 ];
  (void) sizeof(type_must_be_complete);
}

class X;

void f()
{
  assert_complete<X>();
}

class X {};

int main() {}

Si la definición deX falta o en una unidad de traducción diferente, recibo errores.

Pero en el programa como arriba, no es la definición def el único punto de instanciación de mi plantilla? Y no es lo incompleto deX en ese punto de instanciación, ¿un error semántico?

¿El estándar (C ++ 03 y / o C ++ 11 Borrador) llama a este programa bien formado, mal formado, mal formado pero no se requiere diagnóstico o comportamiento indefinido?

Edit: @David Rodriguez - dribeas informa que clang ++, comeau y Visual Studio 2010 también aceptan un código similar.

Respuestas a la pregunta(2)

Su respuesta a la pregunta