2011-01-01 59 views
26

tôi có một loạt các chức năng với nguyên mẫu cùng, nóiNguyên mẫu hàm typedef có thể được sử dụng trong định nghĩa hàm không?

int func1(int a, int b) { 
    // ... 
} 
int func2(int a, int b) { 
    // ... 
} 
// ... 

Bây giờ, tôi muốn đơn giản hóa định nghĩa và khai của họ. Dĩ nhiên tôi có thể sử dụng một macro như thế:

#define SP_FUNC(name) int name(int a, int b) 

Nhưng tôi muốn giữ nó trong C, vì vậy tôi cố gắng sử dụng specifier lưu trữ typedef cho việc này:

typedef int SpFunc(int a, int b); 

Điều này dường như làm việc tốt cho việc kê khai:

SpFunc func1; // compiles 

nhưng không cho định nghĩa:

SpFunc func1 { 
    // ... 
} 

mà mang lại cho tôi những lỗi sau:

error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 

Có cách nào để làm điều này một cách chính xác hoặc là nó không thể? Để hiểu biết của tôi về C điều này sẽ làm việc, nhưng nó không. Tại sao?


Note, gcc hiểu những gì tôi đang cố gắng để làm, bởi vì, nếu tôi viết

SpFunc func1 = { /* ... */ } 

nó nói với tôi

error: function 'func1' is initialized like a variable 

Có nghĩa là gcc hiểu rằng SpFunc là một chức năng kiểu.

Trả lời

39

Bạn có thể không định nghĩa một hàm sử dụng typedef cho một kiểu hàm. Nó bị cấm - hãy tham khảo 6.9.1/2 và chú thích được liên kết:

The identifier declared in a function definition (which is the name of the function) shall have a function type, as specified by the declarator portion of the function definition.

The intent is that the type category in a function definition cannot be inherited from a typedef:

typedef int F(void); // type F is "function with no parameters 
        // returning int" 
F f, g; // f and g both have type compatible with F 
F f { /* ... */ } // WRONG: syntax/constraint error 
F g() { /* ... */ } // WRONG: declares that g returns a function 
int f(void) { /* ... */ } // RIGHT: f has type compatible with F 
int g() { /* ... */ } // RIGHT: g has type compatible with F 
F *e(void) { /* ... */ } // e returns a pointer to a function 
F *((e))(void) { /* ... */ } // same: parentheses irrelevant 
int (*fp)(void); // fp points to a function that has type F 
F *Fp; //Fp points to a function that has type F 
+0

Tôi sợ điều này. Cảm ơn bạn đã xác nhận điều này. Có lý do nào cho việc này không? Dường như với tôi như một tính năng hữu ích. – bitmask

+7

@bitmask: các hàm có thể chia sẻ typedef, nhưng có các đối số được đặt tên khác nhau - tên không phải là một phần của chữ ký hàm và thậm chí có thể bị bỏ qua nếu khai báo không phải là một phần của định nghĩa – Christoph

0

A typedef xác định loại, không phải là tiêu đề (là văn bản mã nguồn). Bạn phải sử dụng #define (mặc dù tôi không khuyên bạn nên dùng nó) nếu bạn cần đưa ra mã cho tiêu đề.

([Edited] Lý do đầu tiên hoạt động là nó không xác định một nguyên mẫu -. Nó xác định một biến kiểu định nghĩa bởi typedef, mà không phải là những gì bạn muốn)

+1

Không, đây không phải là loại con trỏ. Đó sẽ là 'typedef int (* SpFunc) (int a, int b);'. Và kể từ khi khai báo hợp lệ, nó là một kiểu hàm thích hợp. Câu hỏi đặt ra là tại sao tôi không thể sử dụng nó cho định nghĩa. – bitmask

+0

Rất tiếc, đã không thấy dấu hoa thị. Cảm ơn vì sự đúng đắn của bạn. – Mehrdad

+0

Phản hồi này là gì? Đó là đề cập duy nhất của "tiêu đề" trên trang. –

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