Aquí está mi código:
#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;
}
que se compila bien.
Sin embargo, cuando comento esta línea:
//ptr = (struct sockaddr_in *) res->ai_addr;
Obtendré:
$ gcc ex4.c
ex4.c:30:9: error: expected expression
struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
^
1 error generated.
¿Qué me estoy perdiendo?
case
(sin llaves alrededor como lo sugiere la respuesta superior) es una mala idea porque entonces el nombre de la variable será visible en los últimoscase
s, pero no estará inicializado (a menos que baje).Respuestas:
Cada caso en una declaración de cambio es, técnicamente hablando, una etiqueta. Por algunas razones antiguas y oscuras , no se le permite tener una declaración de variable como primera línea después de una etiqueta. Al comentar la tarea
la línea
struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
se convierte en la primera línea después de la etiqueta
AF_INET:
que, como dije, es ilegal en C.La solución es envolver todas las declaraciones de su caso entre corchetes de esta manera:
#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; }
De todos modos, creo que esta es una mejor práctica de codificación.
fuente
Como complemento a la respuesta aceptada, puede declarar sus variables antes de las etiquetas del caso.
switch(a) { int b; //can't initialize variable here case 0: ... }
O simplemente use una declaración vacía.
fuente