Ta odpowiedź jest inspirowana przypadkiem, w którym uzasadnienie Arne'a było poprawne. Dostawca napisał bibliotekę, która kiedyś obsługiwała zarówno C, jak i C ++; Jednak najnowsza wersja obsługiwała tylko C. Następujące śladowe dyrektywy pozostawione w kodzie wprowadzały w błąd:
#ifdef __cplusplus
extern "C" {
#endif
Kosztowało mnie to kilka godzin przy próbie kompilacji w C ++. Samo wywołanie C z C ++ było znacznie łatwiejsze.
Konwencja ifdef __cplusplus narusza zasadę pojedynczej odpowiedzialności. Kod korzystający z tej konwencji próbuje jednocześnie wykonać dwie rzeczy:
- (1) wykonaj funkcję w C - i -
- (2) wykonują tę samą funkcję w C ++
To tak, jakby próbować pisać jednocześnie po angielsku amerykańskim i brytyjskim. Jest to niepotrzebne wrzucenie #ifdef __thequeensenglish spanner #elif __yankeeenglish wrench #else bezużytecznego narzędzia, które utrudnia odczytanie kodu #endif w kodzie.
W przypadku prostego kodu i małych bibliotek może działać konwencja ifdef __cplusplus; jednakże w przypadku złożonych bibliotek najlepiej jest wybrać jeden lub drugi język i trzymać się go. Obsługa jednego z języków wymaga mniej konserwacji niż próba obsługi obu.
To jest zapis modyfikacji, które wprowadziłem w kodzie Arne, aby skompilować go w systemie 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++
komunikaty o błędach