2016-02-23 14 views
8

Tôi muốn sử dụng các từ khóa C11_Generic để điền vào một đoàn theo kiểu tĩnh, như:_Generic để điền vào một số công đoàn

typedef union { 
    double d; 
    long l; 
    const char*s; 
    void*p; 
} ty; 

#define make_ty(X) _Generic((X),      \ 
          double: (ty){.d=(X)},  \ 
          long: (ty){.l=(X)},   \ 
          const char*: (ty){.s=(X)}, \ 
          default: (ty){.p=(X)}) 

ty from_double(double x) { return make_ty(x); } 
ty from_string(const char*s) { return make_ty(s); } 
ty from_long(long l) { return make_ty(l);} 

nhưng điều này không biên dịch, ví dụ GCC 5.3 cung cấp cho (với gcc -std=c11 -Wall):

u.c: In function ‘from_double’: 
u.c:11:35: error: incompatible types when initializing type ‘const char *’ 
        using type ‘double’ 
       const char*: (ty){.s=(X)}, \ 
           ^
u.c:14:41: note: in expansion of macro ‘make_ty’ 
     ty from_double(double x) { return make_ty(x); } 

BTW, sử dụng gcc -std=c99 -Wall cho cùng một lỗi ...

Hoặc là _Generic chỉ hữu ích cho tgmath.h?

Tôi nghĩ rằng _Generic chọn biểu theo kiểu biên dịch tiếng, vì vậy không sensical (ty){.s=(x)} sẽ được bỏ qua trong from_double ....

(nếu điều đó đã làm việc, tôi sẽ có thể "quá tải" make_ty theo tĩnh, trình biên dịch đã biết, loại đối số ...)

+1

Ok, nhưng ngay cả trong '-std = c11' điều này không hoạt động –

+1

[Câu hỏi này] (http://stackoverflow.com/questions/24743520/incompatible-pointer-types-passing-in-generic-macro) có một vấn đề tương tự và câu trả lời hàng đầu có thể trả lời câu hỏi của bạn –

+0

Các câu trả lời khác trên cùng một chủ đề dường như gợi ý rằng các trường hợp khác không được phép chứa * vi phạm ràng buộc * (loại sai cho trình khởi tạo thực sự là một trong số đó) –

Trả lời

5

Tất cả các chi nhánh của _Generic phải là mã hợp lệ, giống như trong một cái gì đó như if (1) { here; } else { there; }. Để có một giải pháp bạn có thể mang nó theo một cách khác. Xác định các chức năng tương tự như:

inline ty from_double(double x) { return (ty){ .d = x }; } 

cho tất cả các trường hợp của bạn và sau đó có vĩ mô như:

#define make_ty(X) _Generic((X),      \ 
          double: from_double,  \ 
          double: from_long,  \ 
          ...)(X) 

Với khả năng hiển thị thông qua inline trình biên dịch thực sự có khả năng tối ưu hóa mã như vậy và thường sẽ không đi qua gọi con trỏ hàm.

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