2015-06-09 16 views
80

Ecco il mio codice:switch-case non verrà compilato dopo commentando una linea inutilizzata

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 

int main (void) { 

    struct addrinfo hints; 
    memset (&hints, 0, sizeof hints); 

    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM; 
    hints.ai_flags = AI_CANONNAME; 

    struct addrinfo *res; 

    getaddrinfo ("example.com", "http", &hints, &res); 
    printf ("Host: %s\n", "example.com"); 

    void *ptr; 

    while (res != NULL) { 
    printf("AI Family for current addrinfo: %i\n", res->ai_family); 
    switch (res->ai_family) { 
     case AF_INET: 
     ptr = (struct sockaddr_in *) res->ai_addr; 
     struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr; 
     break; 
    } 
    res = res->ai_next; 
    } 
    return 0; 
} 

che compila bene.

Tuttavia quando io commento questa riga:

//ptr = (struct sockaddr_in *) res->ai_addr; 

mi metterò:

$ gcc ex4.c 
ex4.c:30:9: error: expected expression 
     struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr; 
     ^
1 error generated. 

Che cosa mi manca?

+0

Forse il titolo di questa domanda deve essere modificato? Qualcuno più esperto può farlo se è d'accordo? –

+0

Dovresti essere in grado di modificarlo da solo, se lo desideri. Ma sono d'accordo, il titolo potrebbe essere migliore. – QuestionC

+0

@KorayTugay, mi sono messo a correre. –

risposta

109

Ogni caso in un'istruzione switch è, tecnicamente parlando, un'etichetta. Per alcuni obscure and old reasons, non è possibile avere una dichiarazione di variabile come prima riga dopo un'etichetta. Commentando l'assegnazione

ptr = (struct sockaddr_in *) res->ai_addr; 

linea

struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr; 

diventa la prima riga dopo l'etichetta AF_INET: che, come ho detto, è illegale in C.

La soluzione è quella di avvolgere tutto delle vostre affermazioni caso tra parentesi graffe come:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 

int main (void) { 

    struct addrinfo hints; 
    memset (&hints, 0, sizeof hints); 

    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM; 
    hints.ai_flags = AI_CANONNAME; 

    struct addrinfo *res; 

    getaddrinfo ("example.com", "http", &hints, &res); 
    printf ("Host: %s\n", "example.com"); 

    void *ptr; 

    while (res != NULL) { 
    printf("AI Family for current addrinfo: %i\n", res->ai_family); 
    switch (res->ai_family) { 
     case AF_INET: 
     { 
     ptr = (struct sockaddr_in *) res->ai_addr; 
     struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr; 
     break; 
     } 
    } 
    res = res->ai_next; 
    } 
    return 0; 
} 

Qualsiasi modo, penso che questa sia una pratica di codifica migliore.

+22

Bello. Nitpicking "Ogni caso ... è ... una dichiarazione etichettata". E questo è il motivo: le dichiarazioni possono essere etichettate ma non dichiarazioni. –

+4

@KorayTugay A volte i messaggi del compilatore non sono informativi come vogliamo che siano .... a volte sono ** troppo ** informativi (tosse per la tosse C++ stl tosse). –

+0

@johnny_boy Non direi il dump di stl come * informativo * ;-) –

15

Come complemento della risposta accettata, è possibile dichiarare le variabili prima delle etichette del caso.

switch(a) { 
    int b; //can't initialize variable here 
    case 0: 
    ... 
} 

Oppure utilizzare solo una dichiarazione vuota.

Problemi correlati