2017-03-28 57 views
9

我注意到OpenSSL的源代码,here一个奇怪的习惯用语和重复如下:这是什么C成语(if(1))?

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将为sim ilar目的
  • 它可能是一个构造,通过几个有意义的转换变得毫无意义,但该构造有since the introduction of OPENSSL_NO_UI

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

谢谢!

+1

在我看来,它的唯一目的是为了避免和'#else'子句出于任何原因 – StoryTeller

+1

Dup of http://stackoverflow.com/questions/2266060/why-would-somebody-use-an-如果-1-C-预处理程序指令? – CristiFati

+2

@CristiFati - 不,这不是关于'#if 1',因为那个构造在问题中完全不出现。这是关于'if(1)'。 – StoryTeller

回答

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没有定义,所以分支编译。如果一个分支的API使用了更改,它将被编译器发现,并且它可以被修复,而无需测试所有编译时开关。

2

它显然是用来删除不应执行的代码,类似于使用#ifdef编译器开关。大多数情况下,这种奇怪的事情是最糟糕的版本控制。

请注意,这不是建议的做法 - 应该没有源代码存在,永远不会执行任何情况下。使用版本控制是更好的做法,或者如果这不可能使用编译器开关,或者如果这是不可能的,则将代码“注释掉”。

0

声明:

if(1) { 

是始终有一个匹配的右括号左括号。