вторник, 26 апреля 2016 г.

Булевые входные параметры

Вижу странное рвение параметризовать функции булевыми параметрами. Примеры буду черпать из ядра Linux, ну не из рабочего же кода их брать. :)

void imx6sl_set_wait_clk(bool enter);

Считаю такой подход крайне неинтуитивным. Зачастую по коду, в котором этот метод вызывается, не возможно сказать - что означает false или true. Для того, чтобы это понять - ты должен открыть прототип.

Интуитивная понятность очень важна.

И главное, мне не очень понятно, что люди пытаются на этом выгадать?

  static void pt_config_start(bool start)
  {
          u64 ctl;
  
          rdmsrl(MSR_IA32_RTIT_CTL, ctl);
          if (start)
                  ctl |= RTIT_CTL_TRACEEN;
          else
                  ctl &= ~RTIT_CTL_TRACEEN;
          wrmsrl(MSR_IA32_RTIT_CTL, ctl);
  
          if (!start)
                  wmb();
  }
 
Причем по коду эту функцию никогда не вызывают с true... :) Но даже если бы true был бы нужен, гораздо понятнее написать две функции:

  static void pt_config_start()
  {
          u64 ctl;
          rdmsrl(MSR_IA32_RTIT_CTL, ctl);
          wrmsrl(MSR_IA32_RTIT_CTL, ctl | RTIT_CTL_TRACEEN);
          wmb();
  }

  static void pt_config_stop()
  {
          u64 ctl;
          rdmsrl(MSR_IA32_RTIT_CTL, ctl);
          wrmsrl(MSR_IA32_RTIT_CTL, ctl & ~RTIT_CTL_TRACEEN);
  }
 
Но это даже не самая главная польза.
Самая главная польза в том, что вместо

   pt_config_start(true);
   ....
   pt_config_start(false);

Мы будем писать:

   pt_config_start();
   ....
   pt_config_stop();

В первом примере невозможно точно понять, действительно ли true/false oзначает start/stop... Это может быть какая нибудь совершенно другая отвлеченная вещ - типа сохранять ли контекст или не сохранять. Или печатать сообщение или не печатать...

Выходные же параметры использовать, на мой взгляд, вполне допустимо.

int __must_check kstrtobool(const char *s, bool *res);

В отличии от входного аргумента здесь мы должны явно задать переменную, и контекст вызова самодостаточен..

          bool bv;
          rc = kstrtobool(buffer, &bv);

Особенно хорошо получается, если не называть переменную bv. (sic)