Câu trả lời này được lấy cảm hứng từ một trường hợp mà cơ sở lý luận của Arne là đúng. Một nhà cung cấp đã viết một thư viện đã từng hỗ trợ cả C và C ++; tuy nhiên, phiên bản mới nhất chỉ hỗ trợ C. Các chỉ thị tiền nghiệm còn lại trong mã gây hiểu nhầm:
#ifdef __cplusplus
extern "C" {
#endif
Điều này khiến tôi mất vài giờ cố gắng biên dịch bằng C ++. Đơn giản chỉ cần gọi C từ C ++ đã dễ dàng hơn nhiều.
Quy ước ifdef __cplusplus vi phạm nguyên tắc trách nhiệm duy nhất. Mã sử dụng quy ước này đang cố gắng thực hiện hai việc cùng một lúc:
- (1) thực thi một hàm trong C - và -
- (2) thực hiện cùng một hàm trong C ++
Nó giống như cố gắng viết bằng cả tiếng Anh Mỹ và Anh cùng một lúc. Điều này không cần thiết khiến cờ lê #ifdef __thequeensenglish #elif __yankeeenglish cờ lê #else trở thành một công cụ vô dụng khiến mã khó đọc hơn #endif vào mã.
Đối với mã đơn giản và thư viện nhỏ, quy ước ifdef __cplusplus có thể hoạt động; tuy nhiên, đối với các thư viện phức tạp, tốt nhất là chọn ngôn ngữ này hoặc ngôn ngữ kia và gắn bó với nó. Việc hỗ trợ một trong các ngôn ngữ sẽ mất ít thời gian bảo trì hơn là cố gắng hỗ trợ cả hai.
Đây là bản ghi về những sửa đổi tôi đã thực hiện đối với mã của Arne để biên dịch nó trên Ubuntu Linux.
foo.h :
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c
#include "foo.h"
#include <stdio.h>
void foo(void)
{
printf("This Hello World was called in C++ and written in C\n");
}
bar.cpp
extern "C" {
#include "foo.h"
}
int main() {
foo();
return(0);
}
Makefile
myfoobar: bar.o foo.o
g++ -o myfoobar foo.o bar.o
bar.o: bar.cpp
g++ -c -o bar.o bar.cpp
foo.o: foo.c
gcc -c -o foo.o foo.c
g++
thông báo lỗi