2012-02-29 8 views
6

Tại sao không nên extern "C" được chỉ định cho hàm cần được định nghĩa là hàm C? Những gì có hiệu lực sẽ có trên trình biên dịch khi biên dịch các tập tin như là một nguồn C?Chúng tôi có thể sử dụng "C" bên ngoài trong tệp C mà không cần #ifdef __cplusplus không?

Nếu không có hiệu ứng trên trình biên dịch C, chúng tôi không thể chỉ định hàm trong tệp tiêu đề như dưới đây bằng cách xóa séc #ifdef __cplusplus?

extern "C" { 
    int MyFunc(); 
} 

An answer to another question nói rằng #ifdef là cần thiết, nhưng tôi không hiểu tại sao:

Về # 2: __cplusplus sẽ được xác định cho bất kỳ đơn vị soạn thảo đang được chạy qua C++ biên dịch. Nói chung, điều đó có nghĩa là các tệp .cpp và bất kỳ tệp nào được bao gồm trong tệp .cpp đó. Cùng .h (hoặc .hh hoặc .hpp hoặc những gì bạn có) có thể được hiểu là C hoặc C++ vào các thời điểm khác nhau, nếu các đơn vị biên dịch khác nhau bao gồm chúng. Nếu bạn muốn các nguyên mẫu trong tệp .h tham chiếu đến tên biểu tượng C, thì chúng phải có extern "C" khi được hiểu là C++ và chúng không được có extern "C" khi được hiểu là C - do đó kiểm tra #ifdef __cplusplus.

Trả lời

13

Cấu trúc extern "C" là cấu trúc C++ và không được trình biên dịch C công nhận. Thông thường, nó sẽ phát hành một thông báo lỗi cú pháp.

Bí quyết thông thường là xác định macro, ví dụ EXTERN_C, điều đó sẽ mở rộng thành điều khác tùy thuộc vào việc bạn biên dịch bằng C hay C++. Ví dụ:

Trong một tập tin tiêu đề phổ biến:

#ifdef __cplusplus 
#define EXTERN_C extern "C" { 
#define EXTERN_C_END } 
#else 
#define EXTERN_C 
#define EXTERN_C_END 
#endif 

Trong file khác:

EXTERN_C 
int MyFunc(void); 
EXTERN_C_END 
+1

Cảm ơn. Tôi không biết đó là một cấu trúc C++. – Alexander

2

Nếu bạn biên dịch một file nguồn như C, nó sẽ không nhận extern "C", và sẽ thường dẫn đến lỗi biên dịch.

Nếu bạn biên dịch tệp nguồn dưới dạng C++, nó sẽ nhận dạng extern "C" và tên chính xác sẽ được liên kết.

Vì vậy, bạn chỉ có thể sử dụng nó một cách đáng tin cậy để chỉ định tên biểu tượng C cho các tệp bạn biên dịch dưới dạng C++.

Nếu bạn biên dịch nguồn dưới dạng C và C++, hoặc giao diện của bạn dành cho máy khách C và C++, bạn cần chỉ định cách này hay cách khác để khách hàng của bạn có được biểu tượng chính xác khi liên kết (v.v.).

Liên quan: Bạn được phép viết extern "C++" - cho bản dịch C++.