Câu trả lời:
Có, sử dụng -E -dM
tùy chọn thay vì -c. Ví dụ (đưa chúng ra thiết bị xuất chuẩn):
gcc -dM -E - < /dev/null
Dành cho C ++
g++ -dM -E -x c++ - < /dev/null
Từ hướng dẫn gcc :
Thay vì đầu ra bình thường, hãy tạo một danh sách các lệnh '#define' cho tất cả các macro được xác định trong quá trình thực thi bộ tiền xử lý, bao gồm các macro được xác định trước. Điều này cung cấp cho bạn một cách để tìm hiểu những gì được xác định trước trong phiên bản tiền xử lý của bạn. Giả sử bạn không có tập tin foo.h, lệnh
touch foo.h; cpp -dM foo.h
sẽ hiển thị tất cả các macro được xác định trước.
Nếu bạn sử dụng -dM mà không có tùy chọn -E, -dM được hiểu là từ đồng nghĩa của -fdump-rtl-mach.
echo | gcc -dM -E -
hoạt động trên windows.
cpp -dM -E - < NUL
có thể được sử dụng.
Tôi thường làm theo cách này:
$ gcc -dM -E - < /dev/null
Lưu ý rằng một số định nghĩa tiền xử lý phụ thuộc vào các tùy chọn dòng lệnh - bạn có thể kiểm tra các tùy chọn này bằng cách thêm các tùy chọn có liên quan vào dòng lệnh trên. Ví dụ: để xem các tùy chọn SSE3 / SSE4 nào được bật theo mặc định:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
và sau đó so sánh điều này khi -msse4
được chỉ định:
$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
Tương tự, bạn có thể thấy các tùy chọn khác nhau giữa hai bộ tùy chọn dòng lệnh khác nhau, ví dụ: so sánh bộ tiền xử lý xác định cho các mức tối ưu hóa -O0
(không có) và -O3
(đầy đủ):
$ 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
Câu trả lời muộn - Tôi thấy các câu trả lời khác hữu ích - và muốn thêm một chút.
Làm cách nào để loại bỏ các macro tiền xử lý đến từ một tệp tiêu đề cụ thể?
echo "#include <sys/socket.h>" | gcc -E -dM -
hoặc (cảm ơn @mymedia cho gợi ý):
gcc -E -dM -include sys/socket.h - < /dev/null
Cụ thể, tôi muốn xem SOMAXCONN được định nghĩa trên hệ thống của tôi. Tôi biết tôi chỉ có thể mở tệp tiêu đề tiêu chuẩn, nhưng đôi khi tôi phải tìm kiếm xung quanh một chút để tìm vị trí tệp tiêu đề. Thay vào đó tôi chỉ có thể sử dụng một lớp lót này:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
Cách tiếp cận đơn giản ( gcc -dM -E - < /dev/null
) hoạt động tốt cho gcc nhưng không thành công cho g ++. Gần đây tôi yêu cầu một bài kiểm tra cho tính năng C ++ 11 / C ++ 14. Các đề xuất cho tên macro tương ứng của chúng được công bố tại https://isocpp.org/std/ Hiểu-document / sd-6-sg10-feature-test-recommendations . Nhưng:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
luôn luôn thất bại, vì nó âm thầm gọi trình điều khiển C (như thể được gọi bởi gcc
). Bạn có thể thấy điều này bằng cách so sánh đầu ra của nó với gcc hoặc bằng cách thêm tùy chọn dòng lệnh cụ thể của g ++ như (-std = c ++ 11) phát ra thông báo lỗi cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
.
Bởi vì (không phải C ++) gcc sẽ không bao giờ hỗ trợ "Mẫu bí danh" (xem http://www.open-std.org/jtc1/sc22/wg21/docs/ con 2007 / n2258.pdf ), bạn phải thêm -x c++
tùy chọn vào buộc yêu cầu trình biên dịch C ++ (Tín dụng cho việc sử dụng các -x c++
tùy chọn thay vì tệp giả trống đi đến yuyichao, xem bên dưới):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
Sẽ không có đầu ra vì g ++ (phiên bản 4.9.1, mặc định là -std = gnu ++ 98) không bật tính năng C ++ 11 theo mặc định. Để làm như vậy, sử dụng
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
mà cuối cùng mang lại
#define __cpp_alias_templates 200704
lưu ý rằng g ++ 4.9.1 không hỗ trợ "Mẫu bí danh" khi được gọi với -std=c++11
.
-x
đối số g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
nên hoạt động.
Một cách tiếp cận di động hoạt động tốt như nhau trên Linux hoặc Windows (nơi không có / dev / null):
echo | gcc -dM -E -
Đối với c ++, bạn có thể sử dụng (thay thế c++11
bằng bất kỳ phiên bản nào bạn sử dụng):
echo | gcc -x c++ -std=c++11 -dM -E -
Nó hoạt động bằng cách báo gcc cho stdin tiền xử lý (được tạo ra bởi echo) và in tất cả các định nghĩa tiền xử lý (tìm kiếm -dletters
). Nếu bạn muốn biết định nghĩa nào được thêm vào khi bạn bao gồm tệp tiêu đề, bạn có thể sử dụng -dD
tùy chọn tương tự -dM nhưng không bao gồm các macro được xác định trước:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
Tuy nhiên, lưu ý rằng đầu vào trống vẫn tạo ra nhiều định nghĩa với -dD
tùy chọn.
NUL
, bạn sẽ quay lại hình vuông: nó sẽ không hoạt động trên các hệ thống không có nó.
sort
hoạt động hơi khác nhau):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Trong khi làm việc trong một dự án lớn có hệ thống xây dựng phức tạp và khó có thể nhận (hoặc sửa đổi) lệnh gcc / g ++, có một cách khác để xem kết quả của việc mở rộng macro. Chỉ cần xác định lại macro và bạn sẽ nhận được đầu ra tương tự như sau:
file.h: note: this is the location of the previous definition
#define MACRO current_value