programing

왜 일부 커널 프로그래머들은 루프 중에 단순 대신 goto를 사용하는가?

copysource 2022. 8. 11. 23:46
반응형

왜 일부 커널 프로그래머들은 루프 중에 단순 대신 goto를 사용하는가?

C를 배웠을 때 선생님은 하루 종일 "고토 쓰지 마, 나쁜 습관이야, 못생기고 위험해!"라고 말씀하셨어.

일부 는 왜 ""를 합니까?goto예를 들어, 이 기능에서는 단순한 것으로 대체할 수 있습니다.

while(condition) {} 

또는

do {} while(condition);

난 그것을 이해할 수 없다. 고토 대신 ?while/do-while약약면면면면면면면?

이력 컨텍스트:우리는 Dijkstra가 1968년에 Goto Consided Enharious라는 을 썼다는 것을 기억해야 한다. 그때 많은 프로그래머들은 이 글을goto구조화된 프로그래밍을 대체하기 위한 것입니다(if,while,for등 ) 。

44년이라는 않습니다.goto했습니다.구조화된 프로그래밍은 이미 오래 전에 승리했습니다.

케이스 분석:

코드 예는 다음과 같습니다.

    SETUP...
again:
    COMPUTE SOME VALUES...
    if (cmpxchg64(ptr, old_val, val) != old_val)
        goto again;

구조화 버전은 다음과 같습니다.

SETUP...
do {
    COMPUTE SOME VALUES...
} while (cmpxchg64(ptr, old_val, val) != old_val);

구조화 된 버전을 보면 바로 '루프다'라는 생각이 들어요.가 봤을 때, ★★★★★★★★★★★★★★★★★★★★★★★★.goto마지막에는 '다시 시도' 케이스가 있는 스트레이트 라인이라고 생각합니다.

goto에는 둘 다 .SETUP ★★★★★★★★★★★★★★★★★」COMPUTE SOME VALUES대부분의 경우 제어 흐름은 양쪽을 통과한다는 것을 강조합니다.에는 「」가 붙어 .SETUP ★★★★★★★★★★★★★★★★★」COMPUTE SOME VALUES이 서로될 수 있음을

여기서의 질문은 코드에 어떤 종류의 강조점을 두느냐는 것입니다.을 비교해보면 '하다'라고 할 수 .goto'이것'은 다음과 같습니다.

구조화 버전:

if (do_something() != ERR) {
    if (do_something2() != ERR) {
        if (do_something3() != ERR) {
            if (do_something4() != ERR) {
                ...

Goto 버전:

if (do_something() == ERR)  // Straight line
    goto error;             // |
if (do_something2() == ERR) // |
    goto error;             // |
if (do_something3() == ERR) // |
    goto error;             // V
if (do_something4() == ERR) // emphasizes normal control flow
    goto error;

생성된 코드는 기본적으로 동일하기 때문에 오목한 부분과 같은 인쇄상의 문제로 생각할 수 있습니다.

이 예에서는 SMP 서포트를 원래 비 SMP 세이프 방식으로 작성된 코드로 리폼하기 위한 것이라고 생각합니다.의 추가goto again;기능을 재구성하는 것보다 경로가 훨씬 간단하고 덜 침습적입니다.

이 마음에 말할 수 , 이을 피하는 것은합니다.goto★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★goto사용법예와 은 '사용법'(이 예와 다름)'입니다.goto는 함수 내에서 전진할 때만 사용되며 후진할 수 없습니다.에서는, 「 구조」가 「루프 구조」가 .goto필요한 동작을 구현하는 가장 간단하고 명확한 방법입니다(일반적으로 청소 후 오류 발생 시 반환).

매우 좋은 질문입니다.저자만이 확답을 줄 수 있다고 생각합니다.덧붙여 @Izkata의 설명대로 에러 처리에 사용하는 것으로부터 시작되었을지도 모른다고 생각합니다만, 그 후 게이트는 기본적인 루프에도 사용할 수 있게 되었습니다.

에러 처리의 사용법은 시스템 프로그래밍에 있어서 정당한 것이라고 생각합니다.함수는 진행에 따라 점진적으로 메모리를 할당하며 오류가 발생하면 다음과 같이 처리됩니다.goto그 시점부터 역순으로 자원을 해방하기 위한 적절한 라벨.

따라서 첫 번째 할당 후 오류가 발생하면 마지막 오류 레이블로 이동하여 리소스를 하나만 해방합니다.마찬가지로 마지막 할당 후 오류가 발생하면 첫 번째 오류 라벨로 이동하여 해당 라벨에서 실행되며 기능이 종료될 때까지 모든 리소스가 해방됩니다.이러한 패턴은 특히 코드 수정, Valgrind 및 유닛테스트를 강력히 권장할 경우 오류처리에 주의하여 사용할 필요가 있습니다.그러나 다른 접근법보다 가독성과 유지보수가 용이하다는 것은 논란의 여지가 없다.

사용의 황금률goto이른바 스파게티 코드를 피하기 위해서입니다.각각에 선을 긋습니다.goto명세서 및 해당 라벨.선이 교차하는 경우 선을 넘은 것입니다:).이 같은 사용방법goto는 매우 읽기 어렵고 추적하기 어려운 버그의 일반적인 원인입니다.플로우 제어에 의존하는 BASIC 등의 언어에서 버그를 찾을 수 있기 때문입니다.

심플한 루프를 1개만 하면 선을 넘지 않기 때문에 읽기 쉽고 유지보수가 가능하기 때문에 스타일도 크게 좌우됩니다.단, 질문에서 지적하신 바와 같이 언어 제공 루프 키워드를 사용하면 쉽게 할 수 있기 때문에 사용을 피하는 것이 좋습니다.goto루프의 경우, 단순히for,do/while또는while건축물은 디자인적으로 더 우아하다.

언급URL : https://stackoverflow.com/questions/13001067/why-do-some-kernel-programmers-use-goto-instead-of-simple-while-loops

반응형