Ця відповідь натхненна випадком, коли аргументація Арне була правильною. Постачальник написав бібліотеку, яка колись підтримувала як C, так і C ++; однак остання версія підтримувала лише C. Наступні рудиментарні вказівки, залишені в коді, вводили в оману:
#ifdef __cplusplus
extern "C" {
#endif
Це коштувало мені кількох годин спроби скомпілювати в C ++. Просто зателефонувати на C з C ++ було набагато простіше.
Конвенція ifdef __cplusplus порушує принцип єдиної відповідальності. Код, що використовує цю конвенцію, намагається зробити дві речі одночасно:
- (1) виконати функцію на C - і -
- (2) виконати ту саму функцію в C ++
Це все одно, що намагатися писати одночасно американською та британською англійською мовами. Це зайве вкидання гайкового ключа #ifdef __thequeensenglish #elif __yankeeenанглійський ключ # інакше марний інструмент, який ускладнює читання коду #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++
повідомлень про помилки