Switch-case wird nicht kompiliert, nachdem eine unbenutzte Zeile auskommentiert wurde

Lesezeit: 3 Minuten

Benutzeravatar von Koray Tugay
Koray Tugay

Hier ist mein Code:

#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;
}

was gut kompiliert.

Wenn ich jedoch diese Zeile auskommentiere:

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

Ich werde bekommen:

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

Was vermisse ich?

  • Vielleicht sollte der Titel dieser Frage bearbeitet werden? Kann das jemand mit mehr Erfahrung tun, wenn er damit einverstanden ist?

    – Koray Tugay

    9. Juni 2015 um 13:58 Uhr

  • Sie sollten in der Lage sein, es selbst zu bearbeiten, wenn Sie möchten. Aber ich stimme zu, der Titel könnte besser sein.

    – FrageC

    9. Juni 2015 um 15:28 Uhr

  • @KorayTugay, ich habe es versucht.

    – Paul Tucher

    9. Juni 2015 um 16:32 Uhr

  • Eine Variablendeklaration innerhalb von a case (ohne umgebende Klammern, wie in der obersten Antwort vorgeschlagen) ist eine schlechte Idee, da dann der Name der Variablen später sichtbar wird cases, aber es wird nicht initialisiert (es sei denn, Sie sind heruntergefallen).

    – MM

    9. Juni 2015 um 23:56 Uhr

Benutzeravatar von John M
John M

Jeder Fall in einer switch-Anweisung ist technisch gesehen ein Label. Aus einigen obskuren und alten Gründen dürfen Sie keine Variablendeklaration als erste Zeile nach einem Label haben. Indem Sie die Aufgabe auskommentieren

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

die Linie

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

wird zur ersten Zeile nach dem Label AF_INET: was, wie gesagt, in C illegal ist.

Die Lösung besteht darin, alle Ihre Case-Anweisungen wie folgt in geschweifte Klammern einzuschließen:

#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;
}

Jedenfalls denke ich, dass dies eine bessere Codierungspraxis ist.

  • Nett. Nitpicking “Jeder Fall … ist … eine beschriftete Aussage”. Und das ist der Grund: Aussagen können beschriftet werden, aber keine Erklärungen.

    – undur_gongor

    9. Juni 2015 um 8:34 Uhr


  • @KorayTugay Manchmal sind Compiler-Meldungen nicht so informativ, wie wir es uns wünschen … manchmal sind sie es zu informativ (Husten Husten C++ stl Husten Husten).

    – Johannes M

    9. Juni 2015 um 8:36 Uhr

  • @BlueMoon Du hast recht. Wenn du kannst Kaufen ein Tool zur Vereinfachung von C++-STL-Fehlermeldungen, wissen Sie, dass die Informationsdichte unglaublich gering ist!

    – Johannes M

    9. Juni 2015 um 9:07 Uhr

  • oder verschieben Sie einfach Deklarationen vor den Schalterblock

    – Pawel Gatnar

    9. Juni 2015 um 11:16 Uhr

  • @immibis: In C++ sind Deklarationen Statements, weshalb man in C++ Deklarationen ohne Einschränkungen beschriften kann. In C sind Deklarationen keine Anweisungen, weshalb Sie sie nicht kennzeichnen können. Hier ist ein Beispiel, das diesen Unterschied zwischen C und C++ veranschaulicht: stackoverflow.com/a/19830820/187690

    – AnT steht zu Russland

    10. Juni 2015 um 5:31 Uhr


Als Ergänzung zur akzeptierten Antwort können Sie Ihre Variablen vor den Fallbezeichnungen deklarieren.

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

Oder verwenden Sie einfach eine leere Anweisung.

1418660cookie-checkSwitch-case wird nicht kompiliert, nachdem eine unbenutzte Zeile auskommentiert wurde

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy