Какова цель блока if (0) в блоке if-else? - PullRequest
0 голосов
/ 14 ноября 2018

Мой вопрос касается строки, которую я упомянул в теме, и которую я вижу во многих местах внутри рабочего кода.

Общий код выглядит следующим образом:

if (0) {
    // Empty braces
} else if (some_fn_call()) {
    // actual code
} else if (some_other_fn_call()) {
    // another actual code
    ...
} else {
    // default case
}

Другие ветки не имеют отношения к моему вопросу.Мне интересно, что означает помещать if (0) здесь.Фигурные скобки пусты, поэтому я не думаю, что предполагается комментировать какой-то блок кода.Это заставляет компилятор провести некоторую оптимизацию или его намерения отличаются?

Я пытался найти этот явный случай здесь, в SO и в Интернете, но безуспешно.Есть похожие вопросы о JavaScript, но не о C. Есть другой вопрос, Что происходит, когда в условии `if` присваивается ноль? , но обсуждается нулевое присвоение переменной, а не 'if(0) 'само использование.

Ответы [ 15 ]

0 голосов
/ 29 ноября 2018

@ PSkocik отвечает хорошо, но я добавляю свои два цента.Не уверен, должен ли я сделать это как комментарий или как ответ;выбор последнего, потому что ИМХО стоит того, чтобы его видели другие, тогда как комментарии часто невидимы.

Мало того, что я иногда использую

if(0) {
   //deliberately left empty
} else if( cond1 ) {
   //deliberately left empty
} else if( cond2 ) {
   //deliberately left empty
...
} else {
   // no conditions matched
}

Но я также иногда делаю

if( 1 
    && cond1 
    && cond2
    ...
    && condN
) {

или

if( 0 
    || cond1 
    || cond2
    ...
    || condN
) {

для сложных условий.По тем же причинам - проще редактировать, #ifdef и т. Д.

В этом отношении в Perl я сделаю

@array = (  
    elem1,
    elem2,
    ...
    elem1,
) {
  • запятую в конце списка,Я забыл, если запятые являются разделителями или разделителями в списках C и C ++.ИМХО, это одна вещь, которую мы узнали: [ Являются ли запятые в Perl плохой практикой? запятые] это хорошая вещь.Как и в любой новой записи, требуется некоторое время, чтобы привыкнуть.

Я сравниваю код if(0) с lisp

(cond   (test1    action1)
   (test2    action2)
   ...
   (testn   actionn))

, который, как вы уже догадались, я могу сделать отступкак

(cond   
   (test1    action1)
   (test2    action2)
   ...
   (testn   actionn)
)

Иногда я пытался представить, как может выглядеть более понятный для человека синтаксис для этого.

Возможно

IF
:: cond1 THEN code1
:: cond2 THEN code2
...
:: condN THEN codeN
FI

по мотивам Дикстры [https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if][Guarded Язык команд].

Но этот синтаксис подразумевает, что условия оцениваются параллельно, тогда как if...else-if подразумевает последовательную и приоритетную оценку условий.

Я начал делать этот видвещь при написании программ, созданных другими программами, где это особенно удобно.

Пока мы работаем над этим, при написании RTL с использованием старого iHDL от Intel я кодировал такие вещи, как

   IF 0 THEN /*nothing*/
   **FORC i FROM 1 TO 10 DOC** 
   ELSE IF signal%i% THEN    
      // stuff to do if signal%i% is active
   **ENDC** 
   ELSE   
      // nothing matched 
   ENDIF

, где FORC..DOC..ENDC - это конструкция цикла макропроцессора, которая расширяется до

   IF 0 THEN /*nothing*/
   ELSE IF signal1 THEN    
      // stuff to do if signal1 is active
   ELSE IF signal2 THEN    
      // stuff to do if signal2 is active
   ...
   ELSE IF signal100 THEN    
      // stuff to do if signal100 is active
   ELSE   
      // nothing matched 
   ENDIF

Это был код с одним присваиванием, не являющийся императивным, поэтому установка переменной состояния была запрещена, если вам нужно было выполнить такие действия, как поиск первого установленного бита.

   IF 0 THEN /*nothing*/
   ELSE IF signal1 THEN    
      found := 1
   ELSE IF signal2 THEN    
      found := 2
   ...
   ELSE IF signal100 THEN    
      found := 100
   ELSE   
      // nothing matched 
   ENDIF

Comeесли подумать, это, возможно, было первое место, с которым я столкнулся с такими конструкциями.

Кстати, возражения, которые некоторые имели против стиля if (0), - что условия else-if-условия последовательно зависят ине может быть произвольно переупорядочен - не применяется к логикам AND и OR и XOR в RTL - но применяется к коротким замыканиям && и ||.

0 голосов
/ 04 декабря 2018
    Actually according to my opinion, if we put any variable for checking inside
    e.g:-
public static void main(string args[])
{
        var status;
        var empList=_unitofWork.EmpRepository.Get(con=>con.isRetired==true);
        //some code logic 
        if(empList.count>0)
        {
          status=true;
        }
        if(status)
        {
         //do something
        }
        else
        {
        //do something else
        }
}
     if then its dynamically get the value in run time and invoke the logic inside it, else its simply extra line of code i guess.

    Anybody have any depth knowledge why this thing is used....or agree with me.
    kindly respond. 
0 голосов
/ 20 ноября 2018

Эта конструкция может также использоваться в C для реализации общего программирования с безопасностью типов, полагаясь на тот факт, что недоступный код все еще проверяется компилятором:

// this is a generic unsafe function, that will call fun(arg) at a later time
void defer(void *fun, void *arg);

// this is a macro that makes it safer, by checking the argument
// matches the function signature
#define DEFER(f, arg) \
   if(0) f(arg); \              // never actually called, but compile-time checked
   else defer(f, (void *)arg);  // do the unsafe call after safety check

void myfunction(int *p);

DEFER(myfunction, 42);     // compile error
int *b;
DEFER(myfunction, b);      // compiles OK
0 голосов
/ 21 ноября 2018

Помогает отладить этот блок, просто помещая блок if 1. Это отключает все функции блока if else.А также мы можем расширить блок if else.

0 голосов
/ 15 ноября 2018

Это код гниения.

В какой-то момент, если «если» что-то сделал, ситуация изменилась, возможно, оцениваемая переменная была удалена.

Человек, который исправлял / изменял систему, сделал как можно меньше, чтобы повлиять на логику системы , поэтому он просто убедился, что код перекомпилируется.Таким образом, он оставляет «если (0)», потому что это быстро и легко, и он не совсем уверен, что это то, что он хочет сделать.Он заставляет систему работать, и он не возвращается, чтобы исправить это полностью.

Затем приходит следующий разработчик и думает, что это было сделано намеренно , и только комментирует эту часть кода (так как она все равно не оценивается), затем при следующем касании кодаэти комментарии удалены.

0 голосов
/ 15 ноября 2018

Одна возможность еще не упомянута: линия if (0) { может быть удобным местом для точки останова.

Отладка часто выполняется для неоптимизированного кода, поэтому всегда будет присутствовать ложный тест, в котором будет установлена ​​точка останова. При компиляции для производства строка кода будет оптимизирована. Эта, казалось бы, бесполезная линия предоставляет функциональные возможности для разработки и тестирования сборок, не влияя на сборки выпуска.

Есть и другие хорошие предложения выше; Единственный способ действительно узнать, в чем заключается цель, - это найти автора и спросить. Ваша система контроля исходного кода может помочь с этим. (Ищите функциональность blame -типа.)

0 голосов
/ 14 ноября 2018

Это может быть полезно, если есть #if операторы, ala

   if (0)
   {
       // Empty block
   }
#if TEST1_ENABLED
   else if (test1())
   {
      action1();
   }
#endif
#if TEST2_ENABLED
   else if (test2())
   {
      action2();
   }
#endif

и т. Д.

В этом случае любой (и все) тесты могут быть #ifи код будет скомпилирован правильно.Почти все компиляторы удаляют часть if (0) {}.Простой автогенератор может генерировать такой код, так как его немного проще кодировать - он не должен рассматривать первый включенный блок отдельно.

0 голосов
/ 15 ноября 2018

Я видел недоступные блоки кода в предварительно расширенном JavaScript, которые были сгенерированы с использованием языка шаблонов.

Например, код, который вы читаете, мог быть вставлен с сервера, который предварительно оценил первое условие, которое в то время полагалось на переменную, доступную только на стороне сервера.

if ( ${requestIsNotHttps} ){ ... }else if( ...

, который когда-то предварительно скомпилировал hences:

if ( 0 ){ ... }else if ( ...

надеюсь, что это поможет вам релятивизировать потенциальную низкую активность клавиатуры эпохи про-утилизации кодеров, к которой я проявляю энтузиазм!

0 голосов
/ 14 ноября 2018

Я видел это несколько раз, я думаю, что наиболее вероятная причина в том, что он оценивал что-то в более старой / другой версии / ветви кода или, возможно, для отладки, и изменение его на if(0) несколько лениво способ удалить все, что было там.

0 голосов
/ 14 ноября 2018

Как написано, предложение if (0) {} компилируется в ничто.

Я подозреваю, что функция предложения в верхней части этой лестницы заключается в предоставлении удобного места для временного отключения всех остальных функций сразу(для целей отладки или сравнения), изменив 0 на 1 или true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...