如果条件后跟while(0)有什么用?

时间:2016-06-18 06:06:54

标签: c linux ping

我正在学习C语言中的ping源代码。

在这里,我被看到一行。这是if条件后跟 while(0)

我在互联网上搜索过。他们给线做后跟while(0)。对于do后跟while(0),我知道答案。但我不知道条件是否跟着而(0)

示例代码是,

if (source.sin_addr.s_addr == 0) {
    socklen_t alen;
    struct sockaddr_in dst = whereto;
    int probe_fd = socket(AF_INET, SOCK_DGRAM, 0);

    if (probe_fd < 0) {
        perror("socket");
        exit(2);
    }
    if (device) {
        struct ifreq ifr;
        int rc;

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, device, IFNAMSIZ-1);

        enable_capability_raw();
        rc = setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1);
        disable_capability_raw();

        if (rc == -1) {
            if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
                struct ip_mreqn imr;
                if (ioctl(probe_fd, SIOCGIFINDEX, &ifr) < 0) {
                    fprintf(stderr, "ping: unknown iface %s\n", device);
                    exit(2);
                }
                memset(&imr, 0, sizeof(imr));
                imr.imr_ifindex = ifr.ifr_ifindex;
                if (setsockopt(probe_fd, SOL_IP, IP_MULTICAST_IF, &imr, sizeof(imr)) == -1) {
                    perror("ping: IP_MULTICAST_IF");
                    exit(2);
                }
            } else {
                perror("ping: SO_BINDTODEVICE");
                exit(2);
            }
        }
    }

    if (settos &&
        setsockopt(probe_fd, IPPROTO_IP, IP_TOS, (char *)&settos, sizeof(int)) < 0)
        perror("Warning: error setting QOS sockopts");

    dst.sin_port = htons(1025);
    if (nroute)
        dst.sin_addr.s_addr = route[0];
    if (connect(probe_fd, (struct sockaddr*)&dst, sizeof(dst)) == -1) {
        if (errno == EACCES) {
            if (broadcast_pings == 0) {
                fprintf(stderr, "Do you want to ping broadcast? Then -b\n");
                exit(2);
            }
            fprintf(stderr, "WARNING: pinging broadcast address\n");
            if (setsockopt(probe_fd, SOL_SOCKET, SO_BROADCAST,
                       &broadcast_pings, sizeof(broadcast_pings)) < 0) {
                perror ("can't set broadcasting");
                exit(2);
            }
            if (connect(probe_fd, (struct sockaddr*)&dst, sizeof(dst)) == -1) {
                perror("connect");
                exit(2);
            }
        } else {
            perror("connect");
            exit(2);
        }
    }
    alen = sizeof(source);
    if (getsockname(probe_fd, (struct sockaddr*)&source, &alen) == -1) {
        perror("getsockname");
        exit(2);
    }
    source.sin_port = 0;

#ifndef WITHOUT_IFADDRS
    if (device) {
        struct ifaddrs *ifa0, *ifa;
        int ret;

        ret = getifaddrs(&ifa0);
        if (ret) {
            fprintf(stderr, "gatifaddrs() failed.\n");
            exit(2);
        }
        for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
            if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
                continue;
            if (!strncmp(ifa->ifa_name, device, sizeof(device) - 1) &&
                !memcmp(&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
                    &source.sin_addr, sizeof(source.sin_addr)))
                break;
        }
        freeifaddrs(ifa0);
        if (!ifa)
            fprintf(stderr, "ping: Warning: source address might be selected on device other than %s.\n", device);
    }
#endif
    close(probe_fd);
} while (0);

在此if after条件下,他们使用while(0)。有什么用呢。

任何人都可以解释一下。

1 个答案:

答案 0 :(得分:4)

你在阅读代码时欺骗了自己。

if (condition) {
    …
}

while (0)
    ;

这就是代码的真正含义。 while循环完全无用(它什么都不做),我无法告诉你为什么会出现这种情况。

要解决此问题,请让您的代码自动格式化。