2009-05-08 5 views
3

http://www0.us.ioccc.org/1988/westley.c에있는 프로그램을보고 있는데, another SO answer에 언급되어 있습니다. 파이의 값을 3.142로 인쇄해야합니다. 그러나 컴파일하고 실행하면 0.250이됩니다. GCC의 전처리 (테스트 모두 4.1.2과 3.4.6)이 코드를 실행하면 프로그램이 작동하려면, 그것은#define은 매크로 주위에 공백을 추가해야합니까?

#define _ -F<00||--F-OO--; 
_-_-_ 

-F<00||--F-OO--;- -F<00||--F-OO--;- -F<00||--F-OO--; 

에 변환하지만 내가 생각하는 것처럼 보인다 그것은이어야합니다

-F<00||--F-OO--;--F<00||--F-OO--;--F<00||--F-OO--; 

예 : GCC는 "매크로"확장 전에 여분의 공간을 삽입하고 있습니다. 그게 #define가 작동하도록되어있는 방법입니까? (1988 년 이후로 바뀌 었습니까?)

EDIT : 또한 이러한 공백이 표시되지 않도록하는 방법에 대한 정보는 감사하겠습니다. 나는이 동작은 표준을 준수 알고

답변

6

전처리 토큰에, 엄격하게 텍스트를 운영하고 있습니다. 그래서 기술적으로는 그 사이에 "공백"을 두지 않지만, 두 개의 토큰을 붙여 넣기를 명시 적으로하지 않으면 매크로가 일치하지 않습니다.이 경우 두 개의 매크로 라인을 가로 지르는 두 개의 매크로는 다음과 같이 계산됩니다. 두 개의 서로 다른 토큰 - 모두 단일 값을 의미하며 감소하지 않음을 의미합니다.

참조 : http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation

C99 표준과
+1

이 문맥에서 '-'는 이항 빼기가 아닌 단항 빼기라고 생각합니다. –

+0

나는이 답변을 무슨 일이 일어나는지에 대한 가장 분명한 설명으로 받아 들였습니다 .- 나는 크리스의 의견에 따라 편집했습니다 (나는 그것을 받아들이고 있기 때문에 정확도는 중요합니다). –

0

예, GCC가 삽입되는 여분의 공백은 (지금까지. gcc -E westley.c (의 표준 출력 출력을 확인하여 확인합니다.

+1

OP는 그것이 사실임을 알고 있습니다. 그는 그것이 지원되는지 알고 싶어합니다. –

+0

Chris가 옳습니다. gcc -E의 결과를 확인한 결과 여분의 공백이 삽입되어이 질문을하게되었습니다. –

5

451,515,는 :

형태의 전처리 지시자

# 식별자 교체리스트 개행을

은 각 후속 인스턴스를 일으키는 물체 같은 매크로를 정의 매크로 이름은 나머지 지시문을 구성하는 전처리 토큰의 대체 목록으로 대체됩니다.

그래서 매크로는 토큰에서 작동하며 공백이 필요합니다.

그리고 당신은 당신이 토큰 붙여 넣기 연산자, ##을 사용하여 원하는 출력을 얻을 수 있지만, 당신이 그것을 할 몇 가지 더 매크로 추를 사용해야합니다 :

그래서
#define PASTE2(x, y) x##y 
#define PASTE(x, y) PASTE2(x, y) 

#define _ -F<00||--F-OO--; 


PASTE(PASTE(PASTE(PASTE(_,-),_),-),_) 

나는 이것이이다 모르겠어요 당신을위한 진짜 대답.

당신은 당신이 원하는 expresions 얻기 위해 매크로 덜 추한 설정을 사용할 수 있습니다 - 여전히 공백이있을 것입니다,하지만 공간이 '--'사업자 생성을 방해하지 않습니다

_ PASTE(-,_) PASTE(-,_) 

I을 그래도 그것이 당신이 원하는 것 일지는 의심 스럽습니다.

11

훨씬 더 오래된 선행 프로세서 만이 추가 공간을 삽입하지 않았습니다. C 표준의 1989 버전이 표준화되기 전에 1988 년에 20 년 전에 원본 항목이 제출되었습니다. -traditional-cpp 플래그를 GCC 전 처리기에 전달할 수 있습니다. GCC 전처리 기는 ISO C 전처리 기와 달리 구식 C 전 처리기의 동작을 모방합니다.

+0

좋은 정보. 그리고 이것은 주석이 흔적없이 사라질 곳에 '#define PASTE (x, y) x/**/y'와 같은 것을 사용하여 때때로 토큰 붙여 넣기를 할 것임을 상기시킵니다. –

+0

붙여 넣기의 관용구는 표준위원회가 공식 운영자를 만드는 동기입니다. 일단 주석이 하나의 공백으로 대체되도록 지정하면, 그것은 관용구를 깨뜨렸다. – RBerteig

관련 문제