2009-07-22 67 views
7

Tôi có một chương trình C có nhiều tối ưu hóa có thể được bật hoặc tắt với #define s. Khi tôi chạy chương trình của mình, tôi muốn biết những macro nào đã được định nghĩa trong thời gian biên dịch.In tên và giá trị của macro

Vì vậy, tôi đang cố viết hàm macro để in giá trị thực của macro. Một cái gì đó như thế này:

SHOW_DEFINE(X){\ 
    if(IS_DEFINED(X))\ 
     printf("%s is defined and as the value %d\n", #X, (int)X);\ 
    else\ 
     printf("%s is not defined\n", #X);\ 
} 

Tuy nhiên tôi không biết làm thế nào để làm cho nó làm việc và tôi nghi ngờ nó không phải là có thể, không ai có một ý tưởng về làm thế nào để làm điều đó?

(Lưu ý rằng đây phải lập ngay cả khi vĩ mô không được định nghĩa!)

Trả lời

4

Viết MACRO mở rộng sang một MACRO khác sẽ yêu cầu bộ tiền xử lý chạy hai lần trên đó.
Điều đó không được thực hiện.

Bạn có thể viết một tập tin đơn giản,

// File check-defines.c 
int printCompileTimeDefines() 
{ 
#ifdef DEF1 
    printf ("defined : DEF1\n"); 
#else // DEF1 
    printf ("undefined: DEF1\n"); 
#endif // DEF1 
// and so on... 
} 

Sử dụng cùng thời gian biên dịch xác định dòng trên tập tin này như với các tập tin khác.
Gọi hàm này lúc đầu.

Nếu bạn có #DEFINE dòng bên trong một file nguồn hơn là Makefile,
Di chuyển chúng vào tập tin khác Header và bao gồm tiêu đề mà trên tất cả các file nguồn,
bao gồm check-defines.c này.

Hy vọng rằng, bạn có cùng một bộ định nghĩa được phép trên tất cả các tệp nguồn của bạn.
Nếu không, sẽ thận trọng khi kiểm tra lại chiến lược định nghĩa của bạn.


Để thế hệ tự động hóa của chức năng này,
bạn có thể sử dụng ngôn ngữ vĩ mô M4 (hoặc thậm chí là một AWK script trên thực tế).
M4 trở thành bộ tiền xử lý trước của bạn.

+0

Được chấp nhận cho câu trả lời m4. Điều này trở nên dễ dàng khi bạn thêm một bước tiền xử lý khác. Tôi đã làm SHOW_DEFINE (X, Y, Z ...) thậm chí còn tốt hơn. Tuy nhiên nó làm cho cảm giác bởi vì tôi cần m4 cho các chất liệu khác. – Ben

2
#ifdef MYMACRO 
    printf("MYMACRO defined: %d\r\n", MYMACRO); 
#endif 

Tôi không nghĩ rằng những gì bạn đang cố gắng làm là có thể. Bạn đang yêu cầu thông tin tại thời gian chạy đã được xử lý trước khi biên dịch. Chuỗi "MYMACRO" có nghĩa là không có gì sau khi CPP đã mở rộng nó thành giá trị bên trong chương trình của bạn.

+0

tốt, đây là những gì tôi muốn tránh, vì tôi có nhiều người trong số họ với #ifdef #else #endif. – Ben

2

Bạn không chỉ định trình biên dịch bạn đang sử dụng. Nếu đây là gcc, gcc -E có thể giúp bạn, vì nó dừng sau giai đoạn tiền xử lý và in kết quả tiền xử lý. Nếu bạn khác với kết quả gcc -E với tệp gốc, bạn có thể nhận được một phần của những gì bạn muốn.

2

Tại sao không chỉ đơn giản là thử nghiệm nó với bộ tiền xử lý?

#if defined(X) 
     printf("%s is defined and as the value %d\n", #X, (int)X); 
#else 
     printf("%s is not defined\n", #X); 
#endif 

Một cũng có thể nhúng này trong thử nghiệm khác không in nó mọi:

#if define(SHOW_DEFINE) 
#if defined(X) 
     printf("%s is defined and as the value %d\n", #X, (int)X); 
#else 
     printf("%s is not defined\n", #X); 
#endif 
#endif 
+0

@philippe, Vâng, đó là những gì tôi và kjfletch dường như đã gợi ý. Nhưng anh ấy muốn tránh viết tất cả những điều đó, đó là lý do tại sao tôi đề xuất kịch bản M4 hoặc AWK. – nik

+0

Đây là những gì tôi làm bây giờ, danh sách không bao giờ được cập nhật và nó cần một tập tin đặc biệt chỉ cho mục đích này: ( – Ben

1

Wave library từ tăng có thể hữu ích cũng để làm những gì bạn muốn.Nếu dự án của bạn là đủ lớn, tôi nghĩ rằng nó là giá trị cố gắng. Nó là bộ tiền xử lý C++, nhưng chúng giống nhau theo bất kỳ cách nào :)

1

Tôi tin rằng những gì bạn đang cố gắng làm là không thể. Nếu bạn có thể thay đổi cách làm việc #define của bạn, sau đó tôi đề nghị một cái gì đó như thế này:

#define ON 1 
#define OFF 2 

#define OPTIMIZE_FOO ON 
#define OPTIMIZE_BAR OFF 

#define SHOW_DEFINE(val)\ 
    if(val == ON) printf(#val" is ON\n");\ 
    else printf(#val" is OFF\n"); 
1

Không thể thực sự, vấn đề là một phần "không xác định". Nếu bạn muốn dựa vào các giá trị vĩ mô để kích hoạt/tắt các phần của mã của bạn, sau đó bạn chỉ có thể làm:

#define SHOW_DEFINE(X) \ 
do { \ 
if (X > 0) \ 
    printf("%s %d\n", #X, (int)X); \ 
else \ 
    printf("%s not defined\n", #X); \ 
} while(0) 
25

Chừng nào bạn sẵn sàng đưa lên với một thực tế rằng someString = someString chỉ ra rằng someString chưa được xác định (!?! xem nó như là mã thông báo đã không được định nghĩa lại), sau đó những điều sau đây nên làm:

#include <stdio.h> 

#define STR(x) #x 
#define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x)) 

#define CHARLIE -6 
#define FRED 1 
#define HARRY FRED 
#define NORBERT ON_HOLIDAY 
#define WALLY 

int main() 
{ 
    SHOW_DEFINE(BERT); 
    SHOW_DEFINE(CHARLIE); 
    SHOW_DEFINE(FRED); 
    SHOW_DEFINE(HARRY); 
    SHOW_DEFINE(NORBERT); 
    SHOW_DEFINE(WALLY); 

return 0; 
} 

Đầu ra là:

BERT=BERT 
CHARLIE=-6 
FRED=1 
HARRY=1 
NORBERT=ON_HOLIDAY 
WALLY= 
+1

Nice! – Ben

+0

Và tôi vừa tìm cách vượt qua giới hạn 15 ký tự bình luận .. – Ben

0

Dựa trên Chrisharris, câu trả lời tôi đã làm điều này. Mặc dù câu trả lời của tôi không phải là rất tốt đẹp nó là khá những gì tôi muốn.

#define STR(x) #x 
#define SHOW_DEFINE(x) printf("%s %s\n", #x, strcmp(STR(x),#x)!=0?"is defined":"is NOT defined") 

Chỉ lỗi mà tôi tìm thấy là xác định không đượC#define XXX XXX (với XXX bằng XXX).

0

bạn có thể sử dụng biến số nguyên được khởi tạo để 1. nhân #define với biến này và in giá trị của biến.

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