Questa risposta è ispirata da un caso in cui la logica di Arne era corretta. Un venditore ha scritto una libreria che una volta supportava sia C che C ++; tuttavia, l'ultima versione supportava solo C.Le seguenti direttive vestigiali lasciate nel codice erano fuorvianti:
#ifdef __cplusplus
extern "C" {
#endif
Questo mi è costato diverse ore cercando di compilare in C ++. Chiamare semplicemente C da C ++ è stato molto più semplice.
La convenzione ifdef __cplusplus viola il principio di responsabilità unica. Un codice che utilizza questa convenzione sta cercando di fare due cose contemporaneamente:
- (1) eseguire una funzione in C - e -
- (2) eseguire la stessa funzione in C ++
È come cercare di scrivere contemporaneamente in inglese americano e britannico. Questo sta lanciando inutilmente una chiave #ifdef __thequeensenglish #elif __yankeeenglish wrench #else uno strumento inutile che rende il codice più difficile da leggere #endif nel codice.
Per codice semplice e piccole librerie la convenzione ifdef __cplusplus può funzionare; tuttavia, per biblioteche complesse è meglio scegliere una lingua o l'altra e attenersi ad essa. Supportare una delle lingue richiederà meno manutenzione rispetto al tentativo di supportare entrambe.
Questa è una registrazione delle modifiche che ho apportato al codice di Arne per farlo compilare su 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++
messaggi di errore