Programing

if-else 블록에서 'if (0)'블록의 목적은 무엇입니까?

crosscheck 2020. 6. 20. 10:30
반응형

if-else 블록에서 'if (0)'블록의 목적은 무엇입니까?


내 질문은 내가 주제에서 언급 한 라인과 생산 코드 내부의 많은 곳에서 볼 수있는 라인에 관한 것입니다.

전체 코드는 다음과 같습니다.

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` 조건에서 0이 할당되면 어떻게됩니까? 'if (0)'사용법 자체가 아니라 변수에 대한 제로 할당에 대해 설명합니다.


나는 때때로 이것을 대칭을 위해 사용하기 때문에 나는 else if{첫 번째를 신경 쓰지 않고 내 편집기로 다른 것을 자유롭게 움직일 수있다 if.

의미 적으로

if (0) {
    // Empty braces
} else 

부분은 아무것도하지 않으며 최적화 프로그램을 사용하여 삭제할 수 있습니다.


이것은 #if진술 이있는 경우 유용 할 수 있습니다.

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

기타

이 경우 모든 (그리고 모든) 테스트를 수행 할 수 있으며 #if코드는 올바르게 컴파일됩니다. 거의 모든 컴파일러가 if (0) {}부품 을 제거합니다 . 간단한 자동 생성기는 코딩이 약간 더 쉬우므로 이와 같은 코드를 생성 할 수 있습니다. 첫 번째 활성화 된 블록을 별도로 고려할 필요는 없습니다.


생성 된 코드에서 사용 된 유사한 패턴을 보았습니다. 예를 들어, SQL에서 라이브러리가 다음 where절을 방출하는 것을 보았습니다 .

where 1 = 1

이것은 아마도 다른 기준을 추가하기가 더 쉬울 것입니다. 왜냐하면 모든 추가 기준 and이 첫 번째 기준인지 아닌지를 확인하기위한 추가 검사 대신 추가 될 수 있기 때문 입니다.


작성된 바와 if (0) {}같이이 절은 아무 것도 컴파일하지 않습니다.

이 사다리의 상단에있는 절의 기능은 0a 1또는 로 변경하여 다른 모든 기능을 한 번에 (디버깅 또는 비교 목적으로) 일시적으로 비활성화 할 수있는 쉬운 장소를 제공하는 것 true입니다.


코드 썩음입니다.

어떤 시점에서 "만약"이 유용한 무언가를했다면 상황이 바뀌었고 평가중인 변수가 제거되었을 수도 있습니다.

시스템을 수정 / 변경 한 사람은 가능한 한 시스템의 논리에 영향을 미치 므로 코드를 다시 컴파일해야합니다. 그래서 그는 빠르고 쉬운 "if (0)"을 남기고 자신이하고 싶은 것이 무엇인지 완전히 확신하지 못합니다. 그는 시스템을 작동시키고 시스템을 완전히 고치기 위해 돌아 가지 않습니다.

그런 다음 다음 개발자가 의도적으로 수행되었다고 생각 하고 코드의 해당 부분 만 주석 처리합니다 (어쨌든 평가되지 않기 때문에). 다음에 코드를 만질 때 해당 주석이 제거됩니다.


아직 언급되지 않은 한 가지 가능성 :이 if (0) {회선은 중단 점에 편리한 지점을 제공 할 수 있습니다.

디버깅은 종종 최적화되지 않은 코드에서 수행되므로 항상 거짓 테스트가 수행되고 중단 점이 설정 될 수 있습니다. 프로덕션 용으로 컴파일하면 코드 라인이 최적화됩니다. 겉보기에 쓸모없는 라인은 릴리스 빌드에 영향을 미치지 않고 개발 및 테스트 빌드 기능을 제공합니다.

위의 다른 좋은 제안도 있습니다. 목적이 무엇인지 실제로 아는 유일한 방법은 저자를 추적하고 물어 보는 것입니다. 소스 코드 제어 시스템이 도움이 될 수 있습니다. ( blame유형 기능을 찾으십시오 .)


나는 어떤 최적화도 확신하지 못하지만 내 2 센트 :

이것은 하나의 주요 조건이 제거 된 코드 수정 (초기 if블록 의 함수 호출 )으로 인해 발생했지만 개발자 / 관리자

따라서 관련 if블록 을 제거하는 대신 조건을 변경하고 계속 진행 if(0)했습니다.


템플릿 언어를 사용하여 생성 된 사전 확장 JavaScript에서 도달 할 수없는 코드 블록을 보았습니다.

예를 들어, 읽고있는 코드는 당시 서버 측에서만 사용 가능한 변수에 의존하는 첫 번째 조건을 미리 평가 한 서버에서 붙여 넣을 수있었습니다.

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

한 번 사전 컴파일 된 것입니다.

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

이것이 내가 당신이 열정을 나타내는 프로 재활용 코더 시대의 잠재적 인 낮은 키보드 활동을 상대화하는 데 도움이되기를 바랍니다!


이 구조는 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

나는 그것이 나쁜 코드라고 생각합니다. 컴파일러 탐색기에서 간단한 예제를 작성하면 gcc와 clang if (0)에서 최적화가 완전히 비활성화 된 경우에도 블록에 대한 코드가 생성 되지 않습니다.

https://godbolt.org/z/PETIks

Playing around with removing the if (0) causes no changes to the generated code, so I conclude that this is not an optimization.

It's possible that there used to be something in the top if block which was later removed. In short, it looks like removing it would cause the exact same code to be generated, so feel free to do that.


As it's been said, the zero is evaluated to false, and the branch will likely be optimized out by the compiler.

I've also seen this before in code where a new feature was added and a kill-switch was needed (if something goes wrong with the feature you can just turn it off), and some time later when the kill-switch was removed the programmer didn't also remove the branch, e.g.

if (feature_a_active()) {
    use_feature_a();
} else if (some_fn()) {
   ...

became

if (0) {
   // empty
} else if (some_fn()) {
   ...

It helps to debug this block just putting if block 1. This disable all if else block functionality. And also we can expand the if else block.


    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. 

@PSkocik's answer is fine, but I add my two cents. Unsure if I should do this as a comment, or as an answer; choosing the latter, because IMHO worth others seeing, whereas comments are frequently invisible.

Not only do I occasionally use

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

But I also occasionally do

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

or

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

for complicated conditions. For the same reasons - easier to edit, #ifdef, etc.

For that matter, in Perl I will do

@array = (  
    elem1,
    elem2,
    ...
    elem1,
) {
  • note the comma at the end of the list. I forget if commas are separators or delimiters in C and C++ lists. IMHO this is one thing we have learned: [Are trailing commas in Perl a bad practice? commas] are a good thing. Like any new notation, it takes a while to get used to.

I compare the if(0) code to lisp

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

which, you guessed it, I may indent as

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

I have sometimes tried to imagine what a more human readable syntax for this might look like.

Perhaps

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

inspired by Dikstra's [https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if][Guarded Command Language].

But this syntax implies that the conditions are evaluated in parallel, whereas if...else-if implies sequential and prioritized evaluation of conditions.

I started doing this sort of thing when writing programs that generated other programs, where it is especially convenient.

While we are at it, when writing RTL using Intel's old iHDL, I have coded stuff like

   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

where the FORC..DOC..ENDC is a macro preprocessor loop construct, that expands to

   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

This was single assignment, non-imperative, code, so setting a state variable was not allowed, if you needed to do things like find first set bit.

   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 to think of it, this may have been the first place that I encountered such constructs.

BTW, the objections that some had to the if(0) style - that the else-if-conditions are sequentially dependent and cannot be arbitrarily reordered - do not apply to AND and OR and XOR logic in RTL - but do apply to short-circuit && and ||.


I have seen this a few times, I think the most likely reason is it was evaluating something in an older/different version/branch of the code, or possibly for debugging, and changing it to if(0) is a somewhat lazy way of removing whatever was there.

참고URL : https://stackoverflow.com/questions/53298646/what-is-the-purpose-of-an-if-0-block-in-if-else-block

반응형