Frage Was ist das C-Idiom (if (1))?


Ich habe eine seltsame Sprache in openssl Quellcode bemerkt, Hier und wiederholt unten:

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

Es scheint, dass dieses Stück Code entspricht:

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
}

Ich habe einige Erklärungen ausgeschlossen:

  • es könnte sein, Blockumfang für einzuführen passwds_static, aber das Einschließen if würde einem ähnlichen Zweck dienen
  • es könnte ein Konstrukt sein, das durch mehrere sinnvolle Transformationen bedeutungslos wird, aber dieses Konstrukt ist da seit der Einführung von OPENSSL_NO_UI.

Fehle ich hier etwas? Was sind die Vorteile davon? if (1)? Wird dies in anderen Codebasen verwendet?

Vielen Dank!


9
2018-03-28 08:27


Ursprung


Antworten:


Nach dem Betrachten anderer ähnlicher Orte, Ich habe eine Erklärung gefunden:

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

In den meisten Fällen (einschließlich ihrer CI denke ich), OPENSSL_NO_UI ist nicht definiert, also beide Zweige werden kompiliert. Wenn die API einer der Verzweigungen Änderungen verwendet, wird sie vom Compiler entdeckt und kann repariert werden, ohne dass alle Kompilierzeitschalter getestet werden müssen.


10
2018-03-28 09:01



Es wird anscheinend verwendet, um Code zu entfernen, der nicht ausgeführt werden sollte, ähnlich wie bei der Verwendung #ifdef Compiler-Schalter. Meistens sind seltsame Dinge wie diese eher ein Hinweis auf eine schlechte Versionskontrolle als alles andere.

Bitte beachten Sie, dass dies nicht empfohlen wird - es sollte kein Quellcode vorhanden sein, der niemals ausgeführt wird. Es ist besser, Versionskontrolle zu verwenden, oder wenn das nicht möglich ist, verwenden Sie Compiler-Schalter, oder wenn das nicht möglich ist, dann "den Code auskommentieren".


2
2018-03-28 09:42



die Aussage:

if(1) {

ist, immer eine passende öffnende Klammer für die schließende Klammer zu haben.


0
2018-03-28 15:47