source

무한 루프를 구현할 때 (1) 대 (;;) 대 (C)로 이동하는 동안 사용하는 것에 차이가 있습니까?

manycodes 2023. 9. 3. 16:23
반응형

무한 루프를 구현할 때 (1) 대 (;;) 대 (C)로 이동하는 동안 사용하는 것에 차이가 있습니까?

무한 루프를 구현할 때 사용하는 방법에 차이가 있습니까?while(1)for(;;)goto?

고마워, 첸즈

최적화 도구를 해제하더라도 동일한 값입니다.

예:

#include <stdio.h>

extern void f(void) {
    while(1) {
        putchar(' ');
    }
}

extern void g(void) {
    for(;;){
        putchar(' ');
    }
}

extern void h(void) {
    z:
        putchar(' ');
    goto z;
}

컴파일 대상gcc -O0는 세 가지 기능 모두에 대해 동등한 어셈블리를 제공합니다.

 f:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fb4 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fb8 00708DE2             add               r7,sp,#0x0
 +00008 00000fbc 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fc0 0A0000EB             bl                putchar (stub)
 +00010 00000fc4 FCFFFFEA             b                 loc_000008
 ;
 ;
 g:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fc8 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fcc 00708DE2             add               r7,sp,#0x0
 +00008 00000fd0 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fd4 050000EB             bl                putchar (stub)
 +00010 00000fd8 FCFFFFEA             b                 loc_000008
 ;
 ;
 h:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fdc 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fe0 00708DE2             add               r7,sp,#0x0
 +00008 00000fe4 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fe8 000000EB             bl                putchar (stub)
 +00010 00000fec FCFFFFEA             b                 loc_000008

방금 gcc의 최적화되지 않은 어셈블리 출력을 비교했습니다.

# cat while.c 
int main() {
    while(1) {};
    return 0;
}

# cat forloop.c 
int main() {
    for (;;) { };
    return 0;
}

어셈블리 출력 만들기:

# gcc -S while.c 
# gcc -S forloop.c 

어셈블리 파일 비교:

# diff forloop.s while.s
1c1
<   .file   "forloop.c"
---
>   .file   "while.c"

보시다시피 큰 차이는 없습니다.다음은 출력입니다.

# cat while.s 
    .file   "while.c"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
.L2:
    jmp .L2                    # this is the loop in both cases
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

이것이 동일하다는 기술적인 증거는 아니지만, 99.9%의 경우에 해당한다고 생각합니다.

생성된 어셈블리는 거의 차이가 없습니다.스타일적인 문제에 가깝습니다.

Go to - just ooogly: 뒤로 점프, 명시적인 무한 블록 없음

반면 (1) - 더 낫습니다, 하지만 "경고" 조건을 요구하고 컴파일러(경고 레벨 4) 또는 정적 분석 도구에 의해 경고를 자주 받을 것입니다.

왜냐하면;)이 가장 예쁘지 않을 수도 있지만, 이 구성은 다른 의미를 가질 수 없기 때문입니다(잠시 동안과 비교하면).하지만 어떤 사람들은 (1) "같은" 이유로 선호합니다.

다른 게시물에서 언급한 것처럼 큰 차이는 없지만, 공통적으로 사용해야 하는 이유는for (;;)대신에while (1)정적 분석 도구(및 특정 경고 수준의 일부 컴파일러)는 종종 while 루프에 대해 불평합니다.

Goto는 약간 심술궂지만 다른 코드와 동일한 코드를 생성해야 합니다.개인적으로, 저는 고수합니다.for (;;)(린트를 행복하게 하기 위해) 하지만 저는 아무 문제가 없습니다.while (1).

while(1)그리고.for(;;)는 정확히 동일하며 둘 다 무한 루프를 코드화하는 데 잘 알려진 관용구입니다.

의 사용을 피하고 싶습니다.goto무한 루프에서 벗어나거나 다음 반복으로 진행하려면 다음을 사용합니다.break그리고.continue.

없습니다. 가장 읽기 쉬운 것을 사용하십시오.

주식회사,true다음과 같이 구현됩니다(컴파일러에 따라 다름).

#define TRUE 1

또는

#define TRUE (-1)

AND false는 다음과 같이 구현됩니다.

#define FALSE 0

그렇게while (1)와 동등합니다.while (true)0은 거짓으로 간주되기 때문입니다.

while (1) == for (; ;)정지 조건이 없기 때문에.

이것은 어셈블러로 번역됩니다.

:loop
  ...
  ...
  ...
  goto loop

그래서 만약 어셈블리 코드가 없다면.ret또는exit명령은 무한 루프로 간주됩니다.

제가 기억하는 "해체 시절"과는 큰 차이가 없습니다(컴파일러는 충분히 똑똑합니다).그것은 미학 IMO에 관한 것입니다.

언급URL : https://stackoverflow.com/questions/2288856/when-implementing-an-infinite-loop-is-there-a-difference-in-using-while1-vs-f

반응형