2009-11-27 35 views
6

Cả hai mở rộng Macro & Tạo mã có ưu điểm & nhược điểm. Cách tiếp cận yêu thích của bạn là gì và tại sao? Khi nào chúng ta nên chọn cái kia? Xin vui lòng tư vấn cho. Cảm ơn bạn!Mở rộng macro C/C++ so với tạo mã

mở rộng vĩ mô có thể rất tiện dụng & hữu ích: http://dtemplatelib.sourceforge.net/table.htm

vs

Trong khi Mã thế hệ cung cấp cho bạn rất nhiều mã đẹp: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

Trả lời

2

Đó là một sự đánh đổi. Để tôi lấy một ví dụ. Tôi tình cờ biết về kỹ thuật của differential execution vào khoảng năm 1985, và tôi nghĩ đó là một công cụ thực sự tốt cho việc lập trình giao diện người dùng. Về cơ bản, phải mất chương trình đơn giản có cấu trúc như thế này:

void Foo(..args..){ 
    x = y; 
    if (..some test..){ 
    Bar(arg1, ...) 
    } 
    while(..another test..){ 
    ... 
    } 
    ... 
} 

và mucks với cấu trúc điều khiển như thế này:

void deFoo(..args..){ 
    if (mode & 1){x = y;} 
    {int svmode = mode; if (deIf(..some test..)){ 
    deBar(((mode & 1) arg1 : 0), ...) 
    } mode = svmode;} 
    {int svmode = mode; while(deIf(..another test..)){ 
    ... 
    } mode = svmode;} 
    ... 
} 

Bây giờ, một cách thực sự tốt để làm điều đó sẽ có được để viết một phân tích cú pháp cho C hoặc bất kỳ ngôn ngữ cơ sở là gì, và sau đó đi bộ cây phân tích, tạo ra mã tôi muốn. (Khi tôi làm điều đó ở Lisp, phần đó thật dễ dàng.)

Nhưng ai muốn viết một trình phân tích cú pháp cho C, C++, hay bất cứ thứ gì?

Vì vậy, thay vào đó, tôi chỉ cần viết macro để tôi có thể viết mã như thế này:

void deFoo(..args..){ 
    PROTECT(x = y); 
    IF(..some test..) 
    deBar(PROTECT(arg1), ...) 
    END 
    WHILE(..another test..) 
    ... 
    END 
    ... 
} 

Tuy nhiên, khi tôi làm điều này trong C#, ai đó trong sự khôn ngoan của họ quyết định macro là xấu, và tôi don không muốn viết một trình phân tích cú pháp C#, vì vậy tôi phải làm việc tạo mã bằng tay. Đây là một nỗi đau của hoàng gia, nhưng nó vẫn đáng giá so với cách viết mã thông thường.

+0

+1 cảm ơn Mike. Đó là câu trả lời hay nhất :) – Viet

5

Trong C hoặc C++, mở rộng vĩ mô là nổi tiếng là khó gỡ lỗi. Mặt khác, việc viết trình tạo mã dễ dàng hơn để gỡ lỗi vì nó là một chương trình riêng biệt trong chính nó.

Tuy nhiên, bạn nên lưu ý rằng đây chỉ là giới hạn của bộ tiền xử lý C. Ví dụ: trong họ ngôn ngữ Lisp, việc mở rộng macro là việc tạo mã, chúng giống hệt nhau. Để viết một macro, bạn viết một chương trình (trong Lisp) để biến đổi đầu vào biểu thức S thành một biểu thức S khác, sau đó nó được chuyển tới trình biên dịch.

+0

Cảm ơn bạn đã trả lời, Greg. Phải mất nhiều thời gian hơn để viết một trình tạo mã phong nha và các macro trông giống như một bản hack nhanh để hoàn thành công việc. – Viet

+0

++ Tình cảm của tôi chính xác. Nó sẽ là tốt đẹp nếu có một cách để bước qua tiền xử lý. Mặc dù vậy, tôi thích các macro nếu việc tạo mã đủ đơn giản. –

9

Đối với C++ tôi thích lập trình meta mẫu hoặc tạo mã trên macro, nhưng macro vẫn có sử dụng của chúng.

Ví dụ bạn đã đưa ra với dbtemplatelib có thể được che phủ bằng C++ 0x Variadic Templates, với lợi ích bổ sung như kiểu kiểm tra, vv

+0

Cảm ơn bạn đã đề xuất. Các mẫu cũng có đức tính của chúng. Macro biến thể có nhưng mẫu variadic vẫn chưa được phổ biến như C++ 0x vẫn còn mới. – Viet

+0

Vâng, để được chính xác, nó thậm chí không ra được nêu ra, và nó sẽ là một "c + + 1x". Nhưng các mẫu variadic được thực hiện trong một số trình biên dịch, ví dụ, để sử dụng chúng với gcc, bạn phải thêm "-std = C++ 0x" làm công cụ biên dịch. – hirschhornsalz

3

Cả hai đều có vấn đề. Không giống như các macro, việc tạo mã có thể tạo ra mã có thể đọc được và có thể gỡ lỗi (thậm chí là một từ?), Nhưng nó ít linh hoạt hơn và khó thay đổi hơn.

+0

+1. cảm ơn bạn đã trả lời. – Viet

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