2017-03-28 4 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それ以外にもいくつか意味のある変換が無意味になるコンストラクトかもしれませんが、そのコンストラクトは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- if-1-c-preprocessor-directive? – 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の1つのブランチが変更を使用すると、コンパイラによって検出され、すべてのコンパイル時のスイッチをテストすることなく修正できます。

2

コンパイラスイッチ#ifdefと同様に、実行してはいけないコードを削除するために使用されます。このような奇妙なことのほとんどは、バージョン管理の貧弱さを示すものです。

これはお勧めできません。何も決して実行されないソースコードは存在しないはずです。バージョンコントロールを使用する方が良いですし、コンパイラスイッチを使用することができない場合や、可能でない場合はコードをコメントアウトしてください。

0

声明:

if(1) { 

は常に閉じ括弧のためにブレースを開くマッチングを持つことです。

関連する問題