2010-01-20 16 views
15

En C es posible escribir código antes de la primera etiqueta case. ¿Hay algún caso para el cual sea útil hacer esto o es solo un 'bloque de código muerto'?Código antes del primer 'caso' en una sentencia switch

ej .:

switch (...) { 
    { 
    int a = 0x2a; 
    printf("%d\n", a); 
    } 
    case 0: 
    ... 
} 
+7

pruébalo y mira ??????????? –

+0

Probé muchos ejemplos diferentes y el de arriba es solo para aclarar. Pero siempre hay una posibilidad de que me haya perdido una característica de (GNU) C y se puede hacer algo en esta región. – tur1ng

Respuesta

11

Puede ser útil declarar variables que tienen un alcance limitado al bloque switch (pero tenga en cuenta que cualquier inicializador para esas variables se saltará):

switch (...) 
{ 
    int n; 

    case 0: 
    ... 
} 

En teoría, también se puede poner el código que hay que se llega a utilizar goto.

+0

Si desea una variable en este ámbito, comience un bloque justo antes del cambio y declare la variable allí, es decir, encierre toda la instrucción de cambio en otro conjunto de corchetes. Declararlo dentro del interruptor pero no en un caso no funciona. – Martin

+2

@Martin: las declaraciones de variables * do * funcionan ya que no producen ningún código de salida; simplemente están ahí para que el compilador tenga en cuenta "Ah, conozco esta variable, la he visto allí". – Joey

+0

"se pueden omitir los inicializadores para esas variables" - ¿es así de simple (el inicializador se salta o no), o es un comportamiento indefinido/programa mal formado saltar sobre un inicializador? No puedo recordar –

18

Creo que esto es menos una característica de un artefacto de cómo trata a C switch/-as case sólo una serie de destinos de salto y sin restricciones en la sintaxis. Es por eso que Duff's device funciona y esa es la razón por la cual el código antes del primer case no se ejecutará.

Si nos fijamos en el conjunto generado verá que el código sólo se saltó:

mov ecx, DWORD PTR _x$[ebp] 
    mov DWORD PTR tv64[ebp], ecx 
    cmp DWORD PTR tv64[ebp], 0     ; here begins the switch 
    je SHORT [email protected]       ; jump to case 0 
    jmp SHORT [email protected]       ; jump out of the switch 
; Line 8 
    mov DWORD PTR _a$752[ebp], 42 
; Line 9 
    mov edx, DWORD PTR _a$752[ebp]    ; here we have the dead code 
    push edx 
    push OFFSET $SG754 
    call _printf 
    add esp, 8 
[email protected]:          ; and here case 0 
; Line 12 
    push OFFSET $SG756 
    call _printf 
    add esp, 4 
[email protected]: 
; Line 15 
    xor eax, eax 
    mov esp, ebp 
    pop ebp 
    ret 0 
1

No entiendo lo que buscas. ¿Por qué no simplemente poner el código antes del caso?

int a = 0x2a; 
printf("%d\n", a); 
switch (...) { 
case 0: 
... 
} 

¿No es lo mismo que lo que pretende? (aparte de en su ejemplo, el código nunca se ejecutaría si el compilador no se queja.)

+0

El printf en mi ejemplo fue elegido al azar. – tur1ng

+5

¿Importa? se deben hacer preguntas de todo –

12

El documento estándar C tiene un ejemplo que explica exactamente el comportamiento de este tipo de construcción (6.8.4.2/7 "La sentencia switch"):

EJEMPLO En el fragmento de programa cial fi arti

switch (expr) 
{ 
    int i = 4; 
    f(i); 
case 0: 
    i = 17; 
    /* falls through into default code */ 
default: 
    printf("%d\n", i); 
} 

existe el objeto cuyo identificador es i con la duración de almacenamiento automático (dentro del bloque) pero nunca se inicializa, y así si la expresión de control tiene un valor distinto de cero, la llamada a la función printf tendrá acceso a un valor indeterminado. Del mismo modo, no se puede acceder a la llamada a la función f.

Por lo tanto, aunque esto está permitido, es fácilmente una de esas situaciones "simplemente porque no significa que deba". La construcción es confusa y puede conducir fácilmente al uso de una variable no inicializada, ya que puede no estar muy claro si se produce o no la inicialización.

+1

El documento estándar C se puede encontrar en: http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1336.pdf – tur1ng

Cuestiones relacionadas