Tôi muốn biết ở đâu là tốt hơn để đưađâu là nơi tốt nhất để đặt #ifdef __cplusplus extern "C" {#endif
#ifdef __cplusplus
extern "C" {
#endif
trong một tập tin header C.
Khi bắt đầu hoặc sau khi tất cả các yếu tố khác bao gồm. tại sao ?
Tôi muốn biết ở đâu là tốt hơn để đưađâu là nơi tốt nhất để đặt #ifdef __cplusplus extern "C" {#endif
#ifdef __cplusplus
extern "C" {
#endif
trong một tập tin header C.
Khi bắt đầu hoặc sau khi tất cả các yếu tố khác bao gồm. tại sao ?
Không có quy định nghiêm ngặt về điều này, nhưng lưu ý những điều sau đây.
Chỉ cần biết rằng ý tưởng đằng sau extern "C" là nó làm cho trình biên dịch tạo ra liên kết thân thiện với C. Nếu không, mã được biên dịch bằng trình biên dịch C++ sẽ tìm kiếm các tên bị xáo trộn để liên kết với các bản lưu trữ được biên dịch bằng trình biên dịch C và không thể tìm thấy chúng.
Ví dụ thứ ba: Trên thực tế, có các thư viện C mà tác giả không quan tâm đến C++ và đơn giản là bỏ qua phần "C" bên ngoài. Bây giờ bạn có muốn sửa đổi các tiêu đề nước ngoài hoặc bao gồm các tiêu đề chưa sửa đổi được bao bọc bởi chính bạn 'extern' C ''? Cá nhân tôi thích thứ hai ... – Aconcagua
cấu trúc này được sử dụng để làm cho tên của bạn có sẵn cho một mối liên kết C (giải thích ngắn gọn)
Vì vậy, rõ ràng là bạn muốn sử dụng nó xung quanh chỉ cụ của bạn.
Như thế này:
#ifndef MY_INCLUDE_H_ // include guard
#define MY_INCLUDE_H_
#include <...> // dependencies
#include "..."
#ifdef __cplusplus
extern “C” {
#endif
// ... your types, methods, variables
#ifdef __cplusplus
}
#endif
#endif // MY_INCLUDE_H_
Hoặc cách vòng khác: để cho phép sử dụng các hàm C trong mã C++ ... – Aconcagua
@Aconcagua cần được chú ý trong các tiêu đề C được bao gồm, nhưng như một phương sách cuối cùng, vâng. Nhưng trong tệp .cpp, không có trong tiêu đề. – Offirmo
Vâng, thread cũng được gắn thẻ 'C', vì vậy, từ quan điểm này, ví dụ của bạn thực sự cũng có thể là một tiêu đề C - trừ khi bạn đã bao gồm một số tiêu đề C++ explicite hoặc sử dụng một số mã C++ độc quyền ... – Aconcagua
extern "C"
ảnh hưởng đến cách mã được biên dịch. Các tiêu đề được được thiết kế để được biên dịch cả dưới dạng C và C++ sẽ tự quản lý extern "C"
. Bạn nên không bao giờ đóng một chỉ thị #include
trong khối extern "C"
: nếu tiêu đề có liên quan được thiết kế để biên dịch cả hai cách mà chỉ thị của bạn thừa, và nếu nó không được thiết kế để sử dụng cả hai cách thì đó là lỗi.
Ý của bạn là "được thiết kế" và "không được thiết kế"? – Vincent
extern "C" ảnh hưởng đến liên kết. Khi các hàm C++ được biên dịch, chúng có tên khác nhau, đó là lý do tại sao quá tải trong C++ là có thể. Vì vậy, tên hàm được sửa đổi dựa trên các kiểu và số tham số, do đó, hai hàm có cùng tên sẽ có hai tên biểu tượng khác nhau.
Mã bên trong "C" bên ngoài vẫn là mã C++. Có những hạn chế về những gì bạn có thể làm trong một khối "C" bên ngoài, nhưng tất cả chúng đều liên quan đến nhau.
Bạn có thể muốn bỏ cụm từ "C++ name mangling" vào câu trả lời khác của bạn –
@Jaap Versteegh Tại sao bỏ thuật ngữ đó là thuật ngữ dùng để xác định loại hành vi này? Nếu ai đó muốn đọc thêm về những gì đang xảy ra và tại sao, đây là thuật ngữ họ nên sử dụng để tìm kiếm thêm thông tin. – hobb
@hobb Tôi muốn nói "thả vào" như trong "thêm". Tên mangling là * không * được đề cập trong câu trả lời và giống như bạn nói, đây là tên cho hành vi này. –
Tôi sẽ nói sau khi bao gồm, vì tại sao bạn đưa các nội dung bên trong ifdef? –