2012-02-23 18 views
8

Ok, considere el siguiente código:errores de compilación en tiempo y código inalcanzable

private const int THRESHHOLD = 2; 

static void Main(string[] args) 
{ 
    string hello; 

    if (THRESHHOLD > 1) return; 
    Console.WriteLine(hello);   
} 

Sorprendentemente este código no lanza un "El uso de variable local no asignada 'hola'" Error de compilación tiempo. Simplemente da una advertencia "Código inalcanzable detectado".

Incluso si el código es inalcanzable, sigue siendo un error de tiempo de compilación, creo que lo correcto es lanzar un error de tiempo de compilación. Si tuviera que hacer lo siguiente:

private const int THRESHHOLD = 2; 

static void Main(string[] args) 
{ 
    string hello; 

    if (THRESHHOLD > 1) return; 
    hello.LMFAO();  
} 

Efectivamente, aparece un 'cadena' "no contiene una definición para 'LMFAO' y ningún método de extensión 'LMFAO' aceptar un primer argumento de tipo cadena' 'se puede encontrar (¿falta una directiva using o una referencia de ensamblado?) "error de compilación.

¿Por qué no es lo mismo con el uso de una variable no asignada?

EDIT Cambió la variable const por lo que es menos molesto. Creo que a muchos les falta el sentido de la pregunta, que es whay según el caso, los errores de tiempo de compilación tienen prioridad sobre el código inalcanzable.

+6

Solo me pregunto: ¿Alguna vez quiere que 'TRUE' evalúe a todo menos' verdad'? –

+2

Una variable no utilizada no evitaría que tu código funcione o compila, por lo que es solo un mensaje de advertencia. Intentar utilizar un método no definido evitaría que tu código se ejecute, por lo que es un error. No estoy seguro de entender el problema. – AaronS

+0

@BrianRasmussen ¿Tal vez viene de un lenguaje donde la palabra clave "verdadera" está en mayúsculas? – Servy

Respuesta

12

James Michael de Hare da la jure explicación: la variable local es definitivamente asignado, debido a que el código es inalcanzable y todas las variables locales se asignaron claramente en el código inalcanzable. Dicho de otra manera: el programa es solo un error si hay una forma de observar el estado de la variable local no inicializada. En su programa no hay forma de observar el local, y por lo tanto no es un error.

Ahora, observo que el compilador no tiene que ser infinitamente inteligente. Por ejemplo:

void M() 
{ 
    int x = 0; 
    int y; 
    if (x + 0 == x) return; 
    Console.WriteLine(y); 
} 

Usted y yo sabemos que la última línea del método es inalcanzable, pero el compilador no sabe que debido a que el analizador de accesibilidad no sabe que el cero es la identidad aditiva de números enteros. El compilador cree que la última línea podría ser accesible, y por lo tanto da un error.

Para obtener más información sobre los aspectos de diseño de analizadores de accesibilidad y de asignación definida en lenguajes de programación, ver mis artículos sobre el tema:

http://blogs.msdn.com/b/ericlippert/archive/tags/reachability/

http://blogs.msdn.com/b/ericlippert/archive/tags/definite+assignment/

que observar sin embargo que nadie ha respondido a la pregunta más profunda, que es ¿por qué si el error se suprime en el código inalcanzable? Como nota, damos otros errores de análisis semántico en el código inalcanzable.

Para considerar los pros y los contras de esa decisión, primero debe pensar por qué alguien tendría un código inalcanzable. O es intencionalmente inalcanzable o involuntariamente inalcanzable.

Si es involuntariamente inalcanzable, el programa contiene un error. La advertencia ya llama la atención sobre el problema principal: el código es inalcanzable. Hay algo muy mal con el flujo de control del método si hay un código inalcanzable. Las probabilidades son buenas de que el desarrollador tenga que realizar un cambio serio en el flujo de control del método; cualquier análisis de variables locales que hagamos en el código inalcanzable probablemente sea un ruido engañoso. Deje que el desarrollador corrija el código para que todo sea accesible, y luego, haremos un análisis del código ahora accesible para los errores relacionados con el flujo de control.

Si el código inalcanzable es inalcanzable porque el desarrollador pretende que sea inalcanzable, entonces las probabilidades son buenas que están haciendo algo como esto:

// If we can Blah, then Frob. However, if we cannot Blah and we can Baz, then Foo. 
void M() 
{ 
    int y; 
    // TODO: The Blah method has a bug and always throws right now; fix it later. 
    if (false /* Blah(out y) */) 
    { 
     Frob(y); 
    } 
    else if (Baz(out y)) 
    { 
     Foo(y); 
    } 
} 

caso Frob(y) ser un error en este programa?

+1

Cosas geniales como siempre. Gracias por la respuesta de Eric, y su ejemplo de por qué el comportamiento implementado es deseable lo hace todo mucho más claro. – InBetween

1

Cuando el compilador ve que el código es inalcanzable, no generará código para él, y por lo tanto, no hay ningún problema.

Si saca la línea return, la última línea se volverá a encontrar, el compilador generará un código para ella y le dirá que hay un problema con ella.

12

Si nos fijamos en el C# language specification en la sección 5, se establece que:

Para una variable inicialmente asignado para ser considerado definitivamente asignado en un lugar determinado, una asignación a la variable debe ocurrir en cada posible camino de ejecución que conduce a esa ubicación.

Y aún más en 5.3.3.1:

v se asignaron claramente al comienzo de cualquier declaración inalcanzable.

Como el código no alcanzable no es una ruta de salida posible, no es necesario que se asigne para evitar un error.

En cuanto a su pregunta por qué una función desconocida es un error de compilación en el código inalcanzable y una variable no asignada no lo es. Debes considerar el estándar anterior. El código inalcanzable no significa que no puede ser sintácticamente válido. El código aún tiene que ser compilable, la única diferencia que hace el código inalcanzable es que considera todas las variables inicialmente no asignadas asignadas en ese punto. Pero eso no significa que puedas inyectar algo sintácticamente inválido como una variable o método indefinido.

El mensaje de error para las variables no asignadas también nos da una pista ya que nos dice que una variable inicialmente no asignada debe asignarse antes del uso, pero como el código no está disponible, técnicamente no se está utilizando ...respuesta

+0

Sí, el comportamiento es de acuerdo con las especificaciones. Estaba más interesado en por qué la accesibilidad tiene prioridad sobre la asignación definitiva. El ejemplo de Eric muestra un caso en el que te gustaría que fuera así. Gracias por la respuesta. – InBetween

+0

@InBetween: No se preocupe, él es el gurú :-) –

Cuestiones relacionadas