2011-07-29 16 views
6

WebKit có rất nhiều dòng tiền xử lý như thế này: #if MACRO1(MACRO2)Tuyên bố macro này có hợp pháp C++ hay cái gì khác không? Và nếu nó là hợp pháp như thế nào cho nó hoạt động

Ví dụ:

#if PLATFORM(MAC) || (PLATFORM(QT) && USE(QTKIT)) 
#include "MediaPlayerPrivateQTKit.h" 
#if USE(AVFOUNDATION) 
#include "MediaPlayerPrivateAVFoundationObjC.h" 
#endif 
... 

Vì vậy, suy nghĩ đầu tiên của tôi là họ chức năng giống như macros, nhưng tôi không thể thấy cách đó sẽ làm việc, và tôi không thể tìm thấy bất kỳ #defines cho các macro bất cứ nơi nào trong mã nguồn.

Tôi đã hỏi một kỹ sư khác là gì và anh ấy chưa bao giờ thấy nhiều macro được sử dụng giống như vậy bên trong #if trước đó. Tôi tìm thấy điều này wiki page mà nói về họ nhưng nó vẫn không rõ ràng cho tôi nơi họ đến từ,

Vì vậy, câu hỏi của tôi sau đó: Đây có phải là C++ hợp lệ hoặc nó đang được thay thế bằng mã bằng công cụ/ngôn ngữ khác CMake hoặc cái gì khác, và nếu nó là hợp lệ C + + là có một spec bất cứ ai là nhận thức được rằng cuộc đàm phán về điều này?

Tôi là kỹ sư hỗ trợ cho công cụ Phân tích tĩnh C++ không xử lý cú pháp này. Một khách hàng yêu cầu chúng tôi xử lý nó, nhưng nếu tôi sẽ đưa nó cho kỹ sư cao cấp, tôi muốn không có âm thanh như một thằng ngốc :) Vì vậy, tôi muốn gritty nitty nếu có ai biết điều đó.

+4

Nó nói ngay trong trang wiki bạn đã đăng liên kết cho rằng các macro đó được định nghĩa trong 'Platform.h', bạn có tìm tệp đó không? –

+0

Về mặt kỹ thuật hợp pháp hay không, nếu nó xây dựng với một số trình biên dịch bạn hỗ trợ và một khách hàng có đủ sức mạnh muốn nó thì bạn nên xem xét hỗ trợ nó, ít nhất là sau một lá cờ thời gian chạy, thậm chí nếu nó là macro-d trong CMake hoặc cái gì khác. Nếu đó là CMake-d trong đó bạn có thể đẩy nó trở lại cho khách hàng để làm cho họ làm cho CMake tạo ra mã thực tế được biên dịch rồi phân tích tĩnh đó? – Rup

+0

@ John nó cũng có thể được tạo ra bởi các kịch bản xây dựng và không phải trong thanh toán nguồn. Tradsud, có thực sự bạn đã cố gắng xây dựng WebKit để xem những gì nó làm? – Rup

Trả lời

5

Như đã đề cập trong wiki, trong root/trunk/Source/JavaScriptCore/wtf/Platform.h, chúng tôi có định nghĩa cho từng định nghĩa này. Ví dụ, macro PLATFORM được định nghĩa là:

#define PLATFORM(WTF_FEATURE) \ 
     (defined WTF_PLATFORM_##WTF_FEATURE \ 
     && WTF_PLATFORM_##WTF_FEATURE) 

Giá trị của WTF_FEATURE sẽ được thay thế bằng tên nền tảng để tạo ra một số vĩ mô được đặt tên WTF_PLATFORM_WTF_FEATRE.Ví dụ: với WTF_FEATURE được chuyển vào macro dưới dạng MAC, bạn sẽ kết thúc với việc mở rộng WTF_PLATFORM_MAC. Chỉ thị tiền xử lý defined được kết hợp với logic AND về cơ bản là hỏi liệu giá trị macro đó có được xác định hay không và nếu nó được xác định, nếu giá trị của nó là giá trị "true". Bạn sẽ sử dụng ở đâu đó macro này khác trong tiền xử lý như:

Bạn sẽ không sử dụng nó trong C++ tự như

if (PLATFORM(MAC)) 
{ 
    //...some code 
} 

có thể gây ra một loạt các lỗi từ trình biên dịch từ defined không phải là từ khóa C++ và việc đánh giá và thay thế macro trong mã C++ sẽ kết thúc việc bán chỉ thị tiền xử lý defined vào bất kỳ mã C++ nào trực tiếp được gọi là macro. Đó không phải là C++ hợp lệ.

Cảm ơn Johannes đã chỉ ra một số vấn đề này.

+1

Lạ. Thông số này cho biết "Nếu mã thông báo * được xác định * được tạo ra do quá trình thay thế này hoặc việc sử dụng toán tử đơn nhất đã xác định không khớp với một trong hai dạng đặc biệt trước khi thay thế macro, hành vi không xác định.". Điều đó có nghĩa là mã có hành vi không xác định? Hay tôi đang hiểu sai điều này. –

+0

Trừ khi tôi nhìn thấy một cái gì đó sai, nó không giống như * định nghĩa * đang được tạo ra là kết quả của quá trình thay thế diễn ra trong macro ... nó trông giống như tôi đang được áp dụng như một nhà điều hành đơn nhất ... do đó, về cơ bản nó nói rằng 'WTF_PLATFORM _ ## WTF_FEATURE' phải là một cái gì đó vừa được định nghĩa * và * ước lượng thành giá trị khác 0. – Jason

+0

@litb: sau khi thay thế macro xảy ra, kết quả sẽ được tạo thành tốt miễn là dán cùng nhau bất kỳ giải pháp 'WTF_PLATFORM' và' WTF_FEATURE' nào là định danh. Sau đó, bạn sẽ có 'define some_identifier', là một trong hai biểu mẫu được chỉ định. –

0

Các định nghĩa có thể đến từ các tập lệnh xây dựng. Hầu hết các trình biên dịch C++ cho phép bạn định nghĩa các macro trên dòng lệnh.

Một cách tôi có thể thấy để xác định một macro SỬ DỤNG như trong ví dụ của bạn sẽ là:

#define USE_QTKIT 1 
#define USE(x) USE_ ## x 

Hoặc có thể như:

gcc -DUSE_QTKIT=1 '-DUSE(x)=USE_ ## x' 
3

Chỉ thị #if khoảng hoạt động bằng cách thay thế tất cả các macro, và sau đó thay thế tất cả số nhận dạng và từ khóa của những gì còn lại bởi 0 và sau đó xử lý những gì còn lại có biểu thức liên tục theo các quy tắc của ngôn ngữ C++ (tập con của những quy tắc đó có thể áp dụng cho những gì còn lại thay thế - khá ít :)).

Vì vậy PLATFORM(MAC) có thể mang lại một 1 nếu MAC được định nghĩa là 1, và một MAC nếu nó không được xác định, nếu PLATFORM chỉ đơn giản là định nghĩa là

#define PLATFORM(X) X 

Các kết quả MAC là một định danh và sau đó sẽ là được thay thế bởi 0. Có nhiều khả năng họ đang ghép nối các X thành một cái gì đó như PLATFORM, để hỗ trợ nhiều truy vấn với đối số MAC, kiểm tra sự tồn tại của các macro khác nhau. Là một nhà phát triển của một công cụ "Phân tích tĩnh C++", bạn có thể có quyền truy cập vào thông số C++. Hãy xem khoản 16.1.

+0

+1 cho hai câu cuối cùng của bạn (mặc dù nó đã được chỉnh sửa trước tốt hơn). – ildjarn

+0

+1 ... cảm ơn vì đã chỉ ra các lỗi trong câu trả lời của tôi – Jason

Các vấn đề liên quan