source

C에서 컴파일러 작성자에게 'auto' 키워드가 유용한 이유는 무엇입니까?

ittop 2023. 9. 9. 10:17
반응형

C에서 컴파일러 작성자에게 'auto' 키워드가 유용한 이유는 무엇입니까?

저는 현재 "Expert C Programming - Deep C Secrets"를 읽고 있는데, 방금 이것을 발견했습니다.

지정자 auto필요 없습니다.컴파일러 작성자가 심볼 테이블에 항목을 입력하는 것은 대부분 의미가 있습니다. 즉, "이 스토리지는 컴파일 타임에 정적으로 할당되거나 힙에 동적으로 할당되는 것이 아니라 블록에 입력할 때 자동으로 할당됩니다."라고 말합니다.auto함수 내부에서만 사용할 수 있기 때문에 다른 모든 프로그래머에게는 거의 의미가 없지만 함수의 데이터 선언에는 기본적으로 이 속성이 있습니다.

여기서 같은 질문을 하시는 분이 있던데 답이 없고 댓글로 주는 링크는 왜 C에 그런 키워드가 있는지, B에게 물려받은 것인지, C++11이나 C++11 이전과 다른 점만 설명해 줍니다.

제가 어쨌든 글을 올리는 이유는 다음과 같은 부분에 집중하기 위해서입니다.auto키워드는 컴파일러 작성에 어느 정도 유용하지만, 아이디어나 기호 테이블과의 연결은 무엇일까요?

저는 정말로 C에서 컴파일러를 프로그래밍할 때 잠재적인 사용법에 대해서만 묻기를 고집합니다(C 컴파일러를 코딩하는 것이 아닙니다.

좀 더 명확히 설명해 드리자면, 제가 이 질문을 한 이유는 코드의 예시가 있는지 알고 싶기 때문입니다.auto작성자가 컴파일러를 작성할 때 있을 것이라고 했기 때문에 정당화될 수 있습니다.

여기서 핵심은 내가 이해한 것은auto(의무적인 B에서 상속되었지만 C에서는 쓸모가 없음), 그러나 사용하는 것이 유용한(또는 적어도 쓸모가 없는) 예는 상상할 수 없습니다.

사용할 이유가 전혀 없는 것 같습니다.auto 것이 된 하는 에 나 이 이 나 ?

작성자 답변:방금 밴더린든씨에게 이메일을 보냈는데, 그가 한 말은 다음과 같습니다.

네, 스택 오버플로우로 답변해주신 분들의 의견에 동의합니다.저는 B라는 언어를 사용한 적이 없어서 확실하게 모르지만, 제가 보기에는 "auto"가 B에 있었기 때문에 C에 들어갔을 가능성이 높아 보입니다.

1980년대 C에서 전문적으로 커널과 컴파일러 프로그래밍을 할 때도 "auto"를 사용한 코드를 본 적이 없습니다.

핵심은 자동 키워드가 추가 정보를 추가하지 않기 때문에 중복적이고 불필요하다는 것입니다.그것을 C로 가져온 것은 실수였습니다!

컴파일러 쓰기와 기호표에 대해 말하는 것이 어떤 의미인지에 대해서도 설명을 구했습니다.그의 대답은 다음과 같습니다.

C 소스 코드를 링커 객체(링크 가능한 객체 파일)로 변환하는 컴파일러를 작성하고 있다고 가정합니다.

사용자의 렉서(컴파일러의 앞단)가 사용자 정의 기호(변수일 수도 있고 함수 이름일 수도 있고 상수일 수도 있음)를 구성하는 문자 시퀀스를 찾을 때마다 컴파일러는 해당 이름을 " 기호 테이블"이라고 하는 테이블에 저장합니다.또한 기호에 대해 알고 있는 다른 모든 것을 저장합니다. 변수인 경우 유형을 저장하고 상수인 경우 값을 저장하며 함수를 호출할 수 있다는 것을 알 수 있습니다.또한 이름의 범위(이 기호가 알려진 코드 행)를 저장합니다.심볼 테이블은 컴파일러의 핵심 데이터 구조 중 하나이며, 일부는 객체 파일로 전달됩니다.개체 파일은 외부 코드 개체가 주소를 지정할 수 있는 이름을 알아야 하므로 링크러는 이름을 저장된 개체와 연결할 수 있습니다.

그런 다음 나중에 컴파일러가 같은 이름을 발견하면 컴파일러는 이미 이름에 대해 모두 알고 있는지 심볼 테이블을 찾아봅니다.이름에 대해 저장할 수 있는 유용한 항목 중 하나는 "컴파일러가 이름에 대한 저장소를 할당할 위치"입니다.해당 스토리지는 기호가 범위 내에 있는 한 유지되어야 합니다.따라서 심볼 테이블이 런타임 시에 스토리지를 할당해야 하는 위치를 파악하는 것이 유용합니다.저는 변수가 저장될 수 있는 다양한 장소에 대한 3가지 예를 들었습니다."auto" 키워드는 컴파일러에게 "이것은 변수이므로 이것을 스택에 저장해야 하며 범위는 이것이 에 선언된 함수입니다."라고 말합니다.

이것은 함수 내에 선언된 모든 변수에 이미 적용되기 때문에 컴파일러가 이 사실을 알려줄 필요는 없습니다.이 설명이 일리가 있기를 바랍니다.

제가 그의 진술을 완전히 오해한 것 같습니다.auto할 때 테이블을 의 용도가 수 , 는 C에할때서의볼가는을수을만다것한가서,y가c을만수다것한가et의ste를gs,a,cnneegrttnlauto쓸모없지만, C 컴파일러 작성자들은 그것을 처리하고 이해해야 합니다. 나는 실수를 했고, 였습니다:고는게제를고고다의로은도다의로i은도,gf:dds,re고oy .

아마도 이 문제를 생각하는 가장 좋은 방법은 다음과 같습니다.

  1. "auto"는 C에서 의미적인 효과가 없습니다.
  2. 저희는 B에서 넘어온 것으로 생각하지만 확실하지는 않습니다.
  3. C 코드 컴파일러를 작성하는 사람에게 정보를 전달합니다.
  4. 그러나 그 정보는 컴파일 작성자가 가지고 있는 다른 정보의 복제입니다.
  5. 그래서 컴파일러 작성자는 기호 테이블을 업데이트하기 위해 어느 하나의 정보를 메모할 수 있습니다.
  6. 또는 실제로 두 정보가 일치하는지 확인할 수 있으며 일치하지 않을 경우 오류 메시지를 발행할 수 있습니다.

작업을 40년 C 알 수 한, 한 의 에서 가 을 가 에서 을 auto키워드는 50년 동안 C에서 전혀 쓸모가 없었습니다.

당신의 정확한 질문에 답하자면, C의 컴파일러 작가들에게 키워드가 유용한 이유는 무엇입니까?이것은 전혀 유용하지 않습니다. C 컴파일러 작성자는 키워드로 구문을 분석하고 스토리지 클래스 지정자로 의미를 구현해야 합니다.

60년대 후반에서 70년대 초반에 벨 연구소에서 켄 톰슨과 데니스 리치가 개발한 C 언어의 전신인 B에서 남겨진 것으로 보입니다.저는 B를 사용한 적이 없고 1984년에 인리아에서 만난 피터도 사용한 적이 없다고 생각합니다.

이전, C23 auto함수 범위의 정의에 대한 자동 저장 클래스를 지정하는 데만 사용할 수 있습니다.고서서s게o,ste서.auto 또는 한,히며나른가한는,한는s히가며른나sssygderauto제거할 수 있습니다.C 표준에 포함된 것은 C 언어의 초기 역사에 뿌리를 두고 있을 뿐입니다.

auto는 C++11 이후 C++에서 자동 저장을 사용하든 사용하지 않든 간에 변수 정의에서 유형 추론을 가능하게 하기 위해 사용되어 왔으며 컴파일러는 컴파일러가 초기화자의 유형으로부터 유형을 탐지합니다.

C++ 언어와 C++ 언어에 대한 공통 부분 집합에 대한 수렴을 추진하는 현재의 추세와 함께, C++ 의미론을 본뜬 C23에서 새로운 의미론이 이 키워드에 추가되었지만, 더 제한적입니다.

6.7.1 스토리지급 규격

auto다음을 제외한 다른 모든 것과 함께 나타날 수 있습니다.typedef;

auto파일 범위가 있는 식별자의 선언 지정자에만 나타나거나, 이니셜라이저에서 유형을 유추해야 하는 경우 다른 스토리지 클래스 지정자와 함께 나타납니다.

한다면auto는 다른 저장소 클래스 지정자와 함께 나타나거나 파일 범위의 선언에 나타나는 경우 연결의 저장 기간을 결정하기 위해 무시됩니다.그러면 선언된 유형을 유추할 수 있음을 나타낼 뿐입니다.

유형 추론은 다음과 같이 지정됩니다.

6.7.9 형식 추론

제약

1 유형이 추론되는 선언에는 저장 클래스 지정자가 포함되어야 합니다.auto.

묘사

2 객체의 정의인 이러한 선언에 대하여 init-declarator는 형식 중 하나를 가져야 합니다.

직접 계산기 = 할당-변환
직접-관리자 = {할당-제한}
직접 관리자 = {할당 제한, }

선언된 유형은 lvalue, array to pointer 또는 function to pointer conversion 다음에 할당 식을 나타내는 유형으로, 수식어에 의해 추가적으로 수식되고 선언 지정자에 나타나는 속성에 의해 수정됩니다.직접 선언자가 형식 식별자 속성-지정자-시퀀스opt 아닌 경우, 괄호의 균형 있는 쌍으로 둘러싸여 있으면 동작이 정의되지 않습니다.

유형 추론은 C++에서 매우 유용합니다. 왜냐하면 유형은 매우 복잡하고 변수 정의에서 지정하는 것이 거의 불가능하기 때문입니다. 특히 템플릿을 사용하면 더욱 그렇습니다.반대로, C에서 그것을 사용하는 것은 아마도 생산성에 반해서 코드 가독성을 줄이고 게으름과 오류가 발생하기 쉬운 관행을 부추기는 것일 것입니다.이미 유형의 디프 뒤에 포인터를 숨길 정도로 나빴습니다. 이제 당신은 그것들을 완전히 숨길 수 있습니다.auto키워드.


좀 덜 진지한 이야기로 마무리하자면, 까다로운 면접 테스트에서 이 코드가 컴파일되지 않는 이유를 찾는 데 사용된 것을 본 기억이 납니다.

#include <stdio.h>
#include <string.h>

int main(void) {
    char word[80];
    int auto = 0;
    while (scanf("%79s", word) == 1) {
        if (!strcmp(word, "car")
        ||  !strcmp(word, "auto")
        ||  !strcmp(word, "automobile"))
            auto++;
    }
    printf("cars: %d\n", auto);
    return 0;
}

auto키워드는 실제로 매우 유용했던 B 언어에서 유래했고 컴파일러가 로컬 이름과 로컬이 아닌 이름을 구별할 수 있게 했습니다.extrn키워드):

main()
{
    extrn printf;
    auto x;
    x = 25;
    printf('%d', x);
}

B 언어가 C로 진화했을 때, 그것은 고도의 하위 호환성을 유지했습니다.B에서는 기본적으로 단일 "셀" 유형만 있었기 때문에 C에서는 유형 주석을 옵션 기능으로 도입했습니다.C89년 이전에는auto지역 이름을 소개하는 동일한 목적으로 사용되었습니다.

main()
{
    extern printf();
    auto x; /* type is int by default */
    x = 42;
    printf("%d", x);
}

온라인 컴파일러

언어의 초점이 유형 안전을 시행하는 쪽으로 이동한 후, 필요한 것은auto형식 주석이 있으면 로컬 이름 선언을 구별할 수 있으므로 지정자가 완전히 증발했습니다.

일단은auto는 4개 또는 5개의 스토리지 클래스 지정업체 중 하나입니다.auto,register,static,extern, 그리고 C11부터_Thread_local. C의 모든 변수에는 위 목록의 관련 스토리지 클래스 지정자가 하나씩 있습니다.auto지정되지 않은 경우 기본값이 됩니다.

사용자의 입장에서 볼 때는auto기본값이므로 지정할 필요는1 거의 없으며, 지정하는 것은 노이즈일 뿐입니다. 일반적으로 지정자가 사용되지 않으면 다른 지정자가 더 두드러집니다.

그러나 컴파일러 작가의 관점에서 보면, 모든 변수는 스토리지 클래스의 특정자를 가지고 있기 때문에,auto가장 중요하고, 그들의 입장에 서보면, 당신은 어딘가에 존재하는 것을 상상할 수 있습니다.enum4개(또는 5개)의 서로 다른 지정자와 열거값 중 하나가 첨부된 각 변수 선언을 열거하는 것.

컴파일러에 나타난다는 사실은 언어에 나타난다는 것을 요구하지는 않지만 규칙성이라는 하나의 논거를 제공합니다.그 개념은 그것이 직접적으로 노출되는지 여부와 관계없이 존재하고 그것을 노출하는 데 비용이 거의 들지 않습니다. 그러니 차라리 그렇지 않습니까?

1 @BenVoigt는 사용자가 다음과 같은 다른 스토리지 지정자를 지정하지 못하도록 하기 때문에 매크로에서 유용할 수 있다고 언급했습니다.static, 컴파일러가 두 개의 스토리지 지정자를 받아들이지 않을 것이기 때문입니다.

C의 자동 키워드는 대부분의 프로그래머들에게 그다지 유용하지 않습니다.그러나 컴파일러 작성자에게는 유용할 수 있습니다.

심볼 테이블은 컴파일러가 프로그램의 모든 변수와 함수를 추적하기 위해 사용하는 데이터 구조입니다.컴파일러가 자동 선언을 볼 때, 변수가 스택에 할당될 것임을 알 수 있습니다.이것은 컴파일러가 레지스터에 저장하는 것을 피하는 것과 같이 해당 변수에 대한 코드를 최적화할 수 있다는 것을 의미합니다.

예를 들어, 다음 함수를 생각해 보겠습니다.

void soso(int x) {
  int y = x * 2;
  // The compiler could optimize this code if it knew that y was allocated on the stack.
  int z = y + 3;
}

컴파일러가 스택에 y가 할당된 것을 알고 있다면 레지스터에 y를 저장하는 것을 피할 수 있습니다.이렇게 하면 메모리가 절약되고 기능의 성능이 향상됩니다.

물론 컴파일러가 생성한 코드의 성능을 향상시키기 위해 자동 키워드가 항상 필요한 것은 아닙니다.그러나 코드 최적화를 원하는 컴파일러 작성자에게는 유용한 도구가 될 수 있습니다.

다음은 auto 키워드에 대한 몇 가지 추가 세부 정보입니다.

C에서는 자동 키워드가 필요하지 않습니다.컴파일러는 함수 내부에 선언된 변수가 스택에 할당된다고 자동으로 가정합니다.auto 키워드를 사용하여 함수 이외의 변수를 선언할 수 있습니다.그러나 코드를 읽고 이해하기가 더 어려워질 수 있으므로 권장하지 않습니다.일부 C 컴파일러에서는 자동 키워드를 사용할 수 없습니다.일부 컴파일러는 특정 상황에서만 지원할 수 있습니다.

언급URL : https://stackoverflow.com/questions/76527163/why-is-the-auto-keyword-useful-for-compiler-writers-in-c

반응형