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

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

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

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

편집하다

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

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

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



답변

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

초기 구현은 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유지된다.


답변