GCC 덤프 전 처리기 정의


답변:


304

예, -E -dM-c 대신 옵션을 사용하십시오. 예 (stdout으로 출력) :

 gcc -dM -E - < /dev/null

C ++ 용

 g++ -dM -E -x c++ - < /dev/null

로부터 GCC 설명서 :

일반적인 출력 대신 사전 처리 된 매크로를 포함하여 전 처리기 실행 중에 정의 된 모든 매크로에 대해`#define '지시문 목록을 생성하십시오. 이를 통해 사용중인 프리 프로세서 버전에서 사전 정의 된 사항을 찾을 수 있습니다. foo.h 파일이 없다고 가정하면 명령은

touch foo.h; cpp -dM foo.h

미리 정의 된 모든 매크로가 표시됩니다.

-E 옵션없이 -dM을 사용하면 -dM은 -fdump-rtl-mach의 동의어로 해석됩니다.


4
gcc는 / dev / null이 의미가없는 시스템에 존재합니다.
Pavel P

4
@Pavel은 gcc 또는 전 처리기-cpp와 함께 빈 파일을 사용할 수 있습니다.
Philant

16
대안 답변으로보다 이식 가능한 접근 방식을 추가했습니다 .Windows에서도 echo | gcc -dM -E -작동합니다.
Pavel P

4
이러한 정의가 어디서 왔는지 (즉, 어떤 파일에서) 확인할 수 있습니까?
edam

2
또는 Windows에서 cpp -dM -E - < NUL사용할 수 있습니다.
René Nyffenegger

78

나는 보통 이렇게한다 :

$ gcc -dM -E - < /dev/null

일부 전 처리기 정의는 명령 줄 옵션에 따라 달라집니다. 위의 명령 줄에 관련 옵션을 추가하여 테스트 할 수 있습니다. 예를 들어, 어떤 SSE3 / SSE4 옵션이 기본적으로 활성화되어 있는지 확인하려면 다음을 수행하십시오.

$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1

그런 다음 -msse4이 지정 되면 이것을 비교하십시오 .

$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1

마찬가지로 두 가지 명령 줄 옵션 세트간에 어떤 옵션이 다른지 알 수 있습니다 (예 : 최적화 수준에 대한 전 처리기 정의 비교 -O0(없음) 및 -O3(전체)).

$ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt
$ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt
$ sdiff -s /tmp/O0.txt /tmp/O3.txt 
#define __NO_INLINE__ 1        <
                               > #define __OPTIMIZE__ 1

45

늦은 답변-다른 답변이 유용하다는 것을 알았으며 약간 더 추가하고 싶었습니다.


특정 헤더 파일에서 오는 전 처리기 매크로를 어떻게 덤프합니까?

echo "#include <sys/socket.h>" | gcc -E -dM -

또는 (제안을 위해 @mymedia에게 감사드립니다) :

gcc -E -dM -include sys/socket.h - < /dev/null

특히, 나는 시스템에서 어떤 SOMAXCONN이 정의되어 있는지보고 싶었다. 표준 헤더 파일을 열 수 있다는 것을 알고 있지만 때로는 헤더 파일 위치를 찾기 위해 조금만 검색해야합니다. 대신이 라이너를 사용할 수 있습니다.

$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$ 

1
파이프를 피하기 위해 -include 컴파일러 옵션을 사용할 수 있습니다.
mymedia

31

간단한 접근 방식 ( gcc -dM -E - < /dev/null)은 gcc에서는 잘 작동하지만 g ++에서는 실패합니다. 최근에 C ++ 11 / C ++ 14 기능에 대한 테스트가 필요했습니다. 해당 매크로 이름에 대한 권장 사항은 https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations에 게시되어 있습니다 . 그러나:

g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates

C 드라이버를 자동으로 호출 하기 때문에 항상 실패합니다 (에 의해 호출 된 것처럼 gcc). 출력을 gcc와 비교하거나 (-std = c ++ 11)과 같은 g ++ 관련 명령 행 옵션을 추가하여 오류 메시지를 표시하여이를 확인할 수 cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C있습니다.

(비 C ++) GCC는 것이기 때문에 결코 "템플릿 별칭을"지원하지 (참조 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf을 당신은 추가해야합니다) -x c++에 옵션을 C ++ 컴파일러를 강제로 호출하십시오 ( -x c++빈 더미 파일 대신 옵션 사용에 대한 크레딧은 yuyichao로 이동하십시오 (아래 참조)).

g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates

g ++ (개정판 4.9.1, 기본값은 -std = gnu ++ 98)이 기본적으로 C ++ 11 기능을 사용하지 않기 때문에 출력이 없습니다. 그렇게하려면

g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates

마지막으로 산출

#define __cpp_alias_templates 200704

g ++ 4.9.1은로 호출 할 때 "템플릿 별칭"을 지원한다는 점에 주목하십시오 -std=c++11.


7
더미 파일을 사용할 필요가 없습니다. GCC는 -x주장을 지원 하므로 g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp작동해야합니다.
yuyichao

@yuyichao 감사합니다. 사용하기가 더 쉽습니다. -x 옵션을 알지 못했습니다. 귀하의 의견을 상향 조정하고 원래 답변에 통합했습니다.
hermannk 2012

23

Linux 또는 Windows (/ dev / null이없는 곳)에서 동일하게 작동하는 이식 가능한 접근 방식 :

echo | gcc -dM -E -

C ++의 경우 다음을 사용할 수 있습니다 (사용 c++11하는 버전으로 교체 ).

echo | gcc -x c++ -std=c++11 -dM -E -

gcc에게 stdin (echo에 의해 생성됨)을 전처리하고 모든 전 처리기 정의를 검색 하도록 지시 합니다 (검색 -dletters). 헤더 파일을 포함 할 때 추가 된 정의를 알고 싶다면 -dD-dM과 유사하지만 사전 정의 된 매크로를 포함하지 않는 옵션을 사용할 수 있습니다 .

echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -

그러나 빈 입력은 여전히 -dD옵션으로 많은 정의를 생성합니다 .


6
@rubenvb 그것은 관련이 없습니다. 요점은 적어도 cmd 줄이 Windows와 유닉스에서 똑같이 잘 작동하는 것입니다. 을 사용 NUL하면 정사각형으로 돌아갑니다.없는 시스템에서는 작동하지 않습니다.
Pavel P

2
C ++에 대한 전체 답변 추가, Windows와 Linux 모두에서 작동 ( sort약간 다르게 동작 하지만 ) :echo | gcc -x c++ -std=c++17 -dM -E - | sort
Xeverous

이것은 git-bash에서 빈 출력을 생성합니다.
Lennart Rolland

@LennartRolland gcc가 있습니까? git-bash에서 gcc를 실행할 수 없습니다
Pavel P

@pavel Windows 용 Qt5 바이너리 배포판과 함께 제공되는 mingw32 gcc를 사용합니다.
Lennart Rolland

3

복잡한 빌드 시스템을 가지고 있고 gcc / g ++ 명령을 직접 얻거나 수정하기 어려운 큰 프로젝트에서 작업하는 동안 매크로 확장의 결과를 보는 또 다른 방법이 있습니다. 간단히 매크로를 재정의하면 다음과 유사한 출력을 얻을 수 있습니다.

file.h: note: this is the location of the previous definition
#define MACRO current_value

어떤 경고 플래그가 사용되는지 찾고 있습니다. 당신은 알고 있습니까?
Welgriv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.