GCC의 앵글 브래킷 구현에는 다음이 포함됩니다. 아래 설명 된 이유는 무엇입니까?


11

2.6 계산 포함 섹션 의이 문서 는 다음 단락으로 구성되어 있습니다.

행이 <토큰으로 시작하고> 토큰을 포함하는 토큰 스트림으로 확장되면 <와 첫 번째> 사이의 토큰이 결합되어 포함 할 파일 이름을 형성합니다. 토큰 사이의 공백은 단일 공백으로 줄어 듭니다. 초기 <뒤의 공백은 유지되지만 닫힘 앞의 후행 공백은 무시 됩니다. CPP는 꺾쇠 괄호 포함 규칙에 따라 파일을 검색합니다.

구현이 정의되어 있다는 것을 알고 있지만 GCC에서 왜 이런 식이어야합니까? 위의 강조 표시된 문장을 구체적으로 언급하고 있습니다.

편집하다

위에서 인용 한 단락 이전의 세 번째 단락에 다음과 같은 내용이 있습니다.

매크로를 정의 할 때주의해야합니다. #define텍스트가 아닌 토큰을 저장합니다. 전처리 기는 매크로가의 인수로 사용될 것이라는 것을 알 방법이 없으므로 #include헤더 이름이 아닌 일반 토큰을 생성합니다. 문자열 상수에 충분히 가까운 큰 따옴표 포함을 사용하는 경우 문제가 발생하지 않습니다. 그러나 꺾쇠 괄호를 사용하면 문제가있을 수 있습니다 .

여기에서 어떤 종류의 문제가 지적되고 있는지 아는 사람이 있습니까?


6
최고의 추측은 GCC 개발자가 파일 이름 끝에 공백을 두는 것이 혐오스러운 것이라고 생각합니다.
user3386109

1
선행 및 / 또는 후행 공백이있는 파일 이름은 특히 Windows에서 매우 까다 롭습니다.
Remy Lebeau

1
그것이 그렇게 정의되었다고해서 반드시 그렇게 정의되어야한다는 것을 의미하지는 않습니다. 그것은 표준에 의해 요구되지 않습니다.
eerorika

Visual Studio는 초기 공간과 끝 공간을 모두 제거하므로 다르게 동작합니다. HP aCC는 gcc처럼 작동합니다 (아마도 호환성 이유로).
Slimak

때로는 문서가 단순히 다른 방법 대신 코드가 어떻게 작동하는지 설명합니다. 특히 중요하지 않은 경우 (큰 따옴표를 사용하면 어디서나 사용할 수 있습니다).
rustyx

답변:


8

구현자가 생각하지 않고이 기능을 구현할 때 가장 간단한 방법을 선택했다고 생각합니다.

초기 구현은 2000-07-03 (20 년 전)에 시작된 것으로 보입니다. 관련 부분은 다음과 같습니다 ( source ).

  for (;;)
    {
      t = cpp_get_token (pfile);
      if (t->type == CPP_GREATER || t->type == CPP_EOF)
        break;

      CPP_RESERVE (pfile, TOKEN_LEN (t));
      if (t->flags & PREV_WHITE)
        CPP_PUTC_Q (pfile, ' ');
      pfile->limit = spell_token (pfile, t, pfile->limit);
    }

특히, CPP_GREATER토큰의 메모리를 예약 하기 전에 토큰을 볼 때 (즉, >) 나옵니다 . 토큰이 버퍼에 쓰여지지 않을 때 메모리를 할당 할 필요가 없기 때문에 이치에 맞습니다.

그런 다음 메모리가 예약 된 후에 만 전처리 기가 토큰 앞에 공백이 있는지 확인하고 ( t->flags & PREV_WHITE) 있으면 공백 문자를 버퍼에 씁니다.

이 결과에서 < foo / bar >, 전 만 공백 foo(즉, 초기 이후 <) /bar유지된다.


훌륭하고 훌륭한 답변. GCC에서 코드를 볼 수있는 기회가 처음입니다. 감사합니다.
Ayrosa

그러나 조건 if (t->flags & PREV_WHITE) CPP_PUTC_Q (pfile, ' ');이 문서에서 말한 내용과 모순되는 경우가 아닌가 : "토큰 사이의 공백은 단일 공백으로 줄어 듭니다. ..."?
Ayrosa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.