2009-05-13 47 views
6

Tôi muốn nhận bộ xử lý trước C để tạo macro cho tôi (nghĩa là tôi chỉ sử dụng C99). Tôi muốn viết một macroMacro sản xuất macro trong C?

#define make_macro(in) <...magic here...> 

và khi tôi đặt

make_macro(name1) 
make_macro(name2) 

sau này trong mã này, nó sẽ mở rộng tới

#define name1(...) name1_fn(name1_info, __VA_ARGS__) 
#define name2(...) name2_fn(name2_info, __VA_ARGS__) 

và sau đó tôi sẽ có thể sử dụng name1 và name2 như (các hàm được triển khai macro). Tôi nghĩ rằng tôi đang bị mắc kẹt bằng cách sử dụng macro ở cả hai bước: nó làm cho tinh thần để sử dụng một vĩ mô để liên tục tái điền vào một mẫu, và xử lý đối số variadic sẽ không hoạt động ngoại trừ thông qua một macro.

Vì vậy, những gì đi vào các < ... ma thuật ở đây ...> giữ chỗ để làm điều này? Tại thời điểm này, tôi bắt đầu tin rằng nó không thể trong C99, nhưng có lẽ tôi đang thiếu một số chi tiết cú pháp.

+0

lý do macro? tôi không nhận được điều này "để liên tục điền lại một mẫu" điểm. những gì mẫu, và những gì nạp tiền? –

Trả lời

5

Không thể trong tiêu chuẩn C.

1

Hãy thử #define make_macro(name,...) name##_fn(name##_info, __VA_ARGS__).

Sử dụng như thế này:

make_macro(name1) 
make_macro(name2,1) 

và điều này sẽ tạo ra

name1_fn(name1_info) 
name2_fn(name2_info,1) 
3

Đó là không thể bởi vì vĩ mô được thực hiện chỉ một lần.

này không có nghĩa là bạn không thể sử dụng các macro khác trong macro của bạn nhưng bạn không thể làm

#define TEST #define HALLO 33 

int x = TEST; 

và mong đợi x là 33 sau đó! Những gì bạn sẽ nhận được là một lỗi cú pháp vì bạn đã cố gắng

int x = #define HALLO 33; 

Hoặc có thể trình biên dịch đã phàn nàn về #define trong #define.

3

Bạn đã cân nhắc sử dụng macro M4 chưa? Tôi nghĩ rằng chúng có sẵn trên hầu hết các nền tảng nên không phải là một hạn chế.

M4 GNU page

+1

+1, M4 thường bị bỏ qua và là một công cụ tạo mã rất mạnh mẽ. Tôi muốn mọi người sẽ dừng lại với những câu nói đùa của LISP mỗi lần họ thấy tôi sử dụng nó. –

1

Như tất cả mọi người đã nói, bạn không thể thực hiện chính xác những gì bạn đang yêu cầu.

Bạn có thể có thể làm điều gì đó như thế bằng cách buộc preprocesor C để chạy hai lần, ví dụ, với một quy tắc như thế này trong makefile:

.c.pp: 
    $(CPP) $< -o [email protected] 

Sau đó cung cấp cho tập tin của bạn mở rộng của test.pp . Makefile sẽ chạy nó một lần để tạo tệp .c, và sau đó chạy bình thường trên tệp .c sẽ chạy nó lần thứ hai.

Cá nhân, tôi thà viết kịch bản bên ngoài trong Perl hoặc thứ gì đó để tạo mã C cho tôi; nó sạch hơn một chút so với chơi trò chơi với bộ xử lý trước C. Nó phụ thuộc vào bao nhiêu mã chúng ta đang nói về.

+0

thông minh, nhưng tôi có cảm giác chạy CPP trên đầu ra của CPP có thể gây ra các vấn đề với các dòng như một pragmas và số dòng. – Michael

1

Theo C99 Section 6.10.3.2:

Mỗi # tiền xử lý dấu hiệu trong danh sách thay thế cho một macro chức năng giống như được theo sau là một tham số vì mã thông báo tiền xử lý tiếp theo trong danh sách thay thế.

Vì vậy, bạn chắc chắn có thể đặt #define trong macro nếu bạn có thông số có tên define nhưng nó sẽ không bao giờ làm những gì bạn mong muốn. Điều này thường gây lỗi cho tôi vì tôi phải làm việc trong C và vì vậy không thể sử dụng các mẫu C++.