คำตอบนี้ได้รับแรงบันดาลใจจากกรณีที่เหตุผลของ Arne ถูกต้อง ผู้ขายเขียนไลบรารีซึ่งเคยรองรับทั้ง C และ C ++ อย่างไรก็ตามเวอร์ชันล่าสุดรองรับเฉพาะ C. คำสั่งร่องรอยต่อไปนี้ที่เหลืออยู่ในรหัสทำให้เข้าใจผิด:
#ifdef __cplusplus
extern "C" {
#endif
สิ่งนี้ทำให้ฉันต้องใช้เวลาหลายชั่วโมงในการรวบรวมใน C ++ เพียงแค่เรียก C จาก C ++ ก็ง่ายกว่ามาก
อนุสัญญา ifdef __cplusplus ละเมิดหลักการความรับผิดชอบเดียว รหัสที่ใช้หลักการนี้พยายามทำสองสิ่งพร้อมกัน:
- (1) เรียกใช้ฟังก์ชันใน C - และ -
- (2) เรียกใช้ฟังก์ชันเดียวกันใน C ++
มันเหมือนกับการพยายามเขียนทั้งภาษาอังกฤษแบบอเมริกันและอังกฤษในเวลาเดียวกัน นี่เป็นการโยน #ifdef __thequeensenglish ประแจ #elif __yankeeenglish โดยไม่จำเป็น #else เครื่องมือที่ไร้ประโยชน์ซึ่งทำให้โค้ดอ่าน #endif ลงในโค้ดได้ยากขึ้น
สำหรับโค้ดอย่างง่ายและไลบรารีขนาดเล็กอาจใช้หลักการ ifdef __cplusplus ได้ อย่างไรก็ตามสำหรับไลบรารีที่ซับซ้อนควรเลือกภาษาหนึ่งหรืออีกภาษาหนึ่งและยึดติดกับมัน การสนับสนุนภาษาใดภาษาหนึ่งจะใช้เวลาดูแลรักษาน้อยกว่าการพยายามสนับสนุนทั้งสองภาษา
นี่คือบันทึกการแก้ไขที่ฉันทำกับโค้ดของ Arne เพื่อให้คอมไพล์บน 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++
ข้อความแสดงข้อผิดพลาดได้ไหม