这个C成语是什么(if(1))?

时间:2017-03-28 08:27:44

标签: c openssl idioms conditional-compilation

我在openssl源代码here中注意到一个奇怪的习语,并在下面重复:

if ((in == NULL) && (passwds == NULL)) {
        if (1) {                                    (* <---- HERE *)
#ifndef OPENSSL_NO_UI
            /* build a null-terminated list */
            static char *passwds_static[2] = { NULL, NULL };

            passwds = passwds_static;
            if (in == NULL)
                if (EVP_read_pw_string
                    (passwd_malloc, passwd_malloc_size, "Password: ",
                     !(passed_salt || in_noverify)) != 0)
                    goto end;
            passwds[0] = passwd_malloc;
        } else {
#endif
            BIO_printf(bio_err, "password required\n");
            goto end;
        }
}

似乎这段代码相当于:

if ((in == NULL) && (passwds == NULL)) {
#ifndef OPENSSL_NO_UI
        /* build a null-terminated list */
        static char *passwds_static[2] = { NULL, NULL };

        passwds = passwds_static;
        if (in == NULL)
            if (EVP_read_pw_string
                (passwd_malloc, passwd_malloc_size, "Password: ",
                 !(passed_salt || in_noverify)) != 0)
                goto end;
        passwds[0] = passwd_malloc;
#else
        BIO_printf(bio_err, "password required\n");
        goto end;
#endif
}

我排除了一些解释:

  • 可能会为passwds_static引入块范围,但封闭的if会起到类似的作用
  • 它可能是一个通过几个有意义的转换变得毫无意义的构造,但那个构造是since the introduction of OPENSSL_NO_UI

我在这里遗漏了什么吗?这个if (1)有什么好处?这是否用于其他代码库?

谢谢!

3 个答案:

答案 0 :(得分:10)

在查看其他类似地点后,I found an explanation

if (1) { /* This is a trick we use to avoid bit rot.
          * at least the "else" part will always be
          * compiled.
          */
#ifdef AF_INET6
    family = AF_INET6;
} else {
#endif
    BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
    goto exit_loop;
}

在大多数情况下(包括他们的CI我猜),OPENSSL_NO_UI未定义,因此两个分支都被编译。如果其中一个分支使用了更改,它将由编译器发现,并且可以修复,而无需测试所有编译时开关。

答案 1 :(得分:2)

它显然用于删除不应执行的代码,类似于使用#ifdef编译器开关。大多数情况下,像这样的奇怪的事情表明版本控制比其他任何东西都差。

请注意,这不是建议的做法 - 不应存在任何源环境,在任何情况下都不会执行。更好的做法是使用版本控制,或者如果不可能使用编译器开关,或者如果不可能那么,那么&#34;注释掉&#34;代码。

答案 2 :(得分:0)

声明:

if(1) {

总是有一个匹配的左括号支撑。