एक अप्रयुक्त रेखा से टिप्पणी करने के बाद स्विच-केस संकलित नहीं होगा


82

यहाँ मेरा कोड है:

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

जो ठीक संकलन करता है।

हालाँकि जब मैं इस लाइन पर टिप्पणी करता हूँ:

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

मुझे मिलेगा:

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

मैं क्या खो रहा हूँ?


शायद इस सवाल का शीर्षक संपादित किया जाना चाहिए? क्या कोई और अधिक अनुभवी ऐसा कर सकता है अगर वह इससे सहमत है?
कोरे तुगे

आप चाहें तो इसे स्वयं संपादित कर सकते हैं। लेकिन मैं सहमत हूं, शीर्षक बेहतर हो सकता है।
प्रश्न

@KorayTugay, मैंने इस पर एक रन लिया।
पॉल ड्रेपर

1
किसी के अंदर एक वैरिएबल डिक्लेरेशन होना case(शीर्ष उत्तर द्वारा सुझाए गए ब्रेसेस के बिना) एक बुरा विचार है क्योंकि तब वेरिएबल का नाम बाद के cases में दिखाई देगा, लेकिन यह uninitialized होगा (जब तक कि आप नीचे नहीं गिर जाते)।
एमएम

जवाबों:


111

प्रत्येक मामले में एक स्विच स्टेटमेंट है, तकनीकी रूप से बोलना, एक लेबल। कुछ अस्पष्ट और पुराने कारणों से , आपको लेबल के बाद पहली पंक्ति के रूप में एक चर घोषणा की अनुमति नहीं है। असाइनमेंट को कमेंट करके

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

रेखा

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

लेबल के बाद पहली पंक्ति बन जाती है AF_INET:, जैसा कि मैंने कहा, सी में अवैध है।

समाधान यह है कि आप अपने सभी केस स्टेटमेंट को घुंघराले ब्रैकेट में लपेटें जैसे:

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

वैसे भी, मुझे लगता है कि यह बेहतर कोडिंग अभ्यास है।


22
अच्छा लगा। Nitpicking "प्रत्येक मामला ... है ... एक लेबल-बयान"। और यही कारण है: बयानों को लेबल किया जा सकता है लेकिन घोषणाओं को नहीं।
undur_gongor

4
@KorayTugay कभी-कभी कंपाइलर संदेश सूचनात्मक नहीं होते हैं जैसा कि हम उन्हें चाहते हैं .... कभी-कभी वे बहुत अधिक जानकारीपूर्ण होते हैं (खांसी खांसी C ++ stl खांसी)।
जॉन एम।

5
@BlueMoon आप सही हैं। जब आप C ++ stl त्रुटि संदेशों को सरल बनाने के लिए एक उपकरण खरीद सकते हैं , तो आपको पता है कि सूचना घनत्व अविश्वसनीय रूप से कम है!
जॉन एम।

3
या बस स्विच ब्लॉक से पहले घोषणाओं को आगे
बढ़ाएँ

3
@ आईमिबिस: सी ++ में घोषणाएं बयान हैं, यही कारण है कि सी ++ में आप बिना किसी प्रतिबंध के घोषणाओं को लेबल कर सकते हैं। C घोषणाओं में कथन नहीं हैं, यही वजह है कि आप उन्हें लेबल नहीं कर सकते। यहाँ एक उदाहरण है जो C और C ++ के बीच इस अंतर को दिखाता है: stackoverflow.com/a/19830820/187690
AnT

15

स्वीकृत उत्तर के पूरक के रूप में, आप केस लेबल से पहले अपने चर घोषित कर सकते हैं।

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

या सिर्फ एक खाली बयान का उपयोग करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.