Czy extern " C " jest wymagany tylko w deklaracji funkcji?
Napisałem funkcję C++, którą muszę wywołać z programu C. Aby uczynić ją możliwą do wywołania z C, podałem extern "C"
w funkcji deklaracja. Następnie skompilowałem kod C++, ale kompilator (Dignus Systems/C++) wygenerował zniekształconą nazwę dla funkcji. Więc najwyraźniej nie uszanował extern "C"
.
Aby to rozwiązać, dodałem extern "C"
do definicji funkcji . Następnie kompilator wygenerował nazwę funkcji, którą można wywołać z C.
Technicznie rzecz biorąc, extern "C"
musi być tylko określona w deklaracji funkcji. Czy to prawda? (The C++ FAQ Lite ma tego dobry przykład.) Czy należy go również określić w definicji funkcji?
Oto przykład, aby to zademonstrować:
/* ---------- */
/* "foo.h" */
/* ---------- */
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
/* ---------- */
/* "foo.cpp" */
/* ---------- */
#include "foo.h"
/* Function definition */
extern "C" // <---- Is this needed?
void foo(int i) {
// do something...
}
mój problem może być wynikiem nieprawidłowego kodowania czegoś lub znalazłem błąd kompilatora. W każdym razie chciałem skonsultować się ze stackoverflow, aby upewnić się, że wiem, który jest technicznie "right" way.
6 answers
'extern "C"
' nie powinien być wymagany na definicji funkcji, o ile deklaracja ją posiada i jest już widoczna w kompilacji definicji. Standard określa konkretnie (specyfikacje połączeń 7.5/5):
Funkcja może być zadeklarowana bez specyfikacji powiązania po wyświetleniu jawnej specyfikacji powiązania; powiązanie wyraźnie określone we wcześniejszej deklaracji nie ma wpływu na taką deklarację funkcji.
Jednak Ja ogólnie rzecz biorąc, należy również umieścić 'extern "C"
'Na definicji, ponieważ w rzeczywistości jest to funkcja z zewnętrznym połączeniem "C". Wiele osób nie lubi, gdy zbędne, zbędne rzeczy są na deklaracjach( np. umieszczanie virtual
na nadpisywaniu metod), ale ja nie jestem jednym z nich.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-04 19:00:05
Edit:
Chyba źle zrozumiałem pytanie.
W każdym razie próbowałem:
// foo.cpp
/* Function definition */
#include "foo.h"
void foo(int i) {
//do stuff
}
void test(int i)
{
// do stuff
}
// foo.h
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
void test(int);
Użycie polecenia nm
do wyświetlenia symboli ze skompilowanego pliku:
linuxuser$ nm foo.o
00000006 T _Z4testi
U __gxx_personality_v0
00000000 T foo
To wyraźnie sugeruje, że nazwa funkcji zadeklarowanej jako extern " C "nie jest zniekształcona, a słowo kluczowe extern" C " nie jest wymagane w definicji.
Gdyby wymagało to, aby każdy kod biblioteki C napisany bez extern " C " byłby bezużyteczny w programach C++.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-04 19:48:04
Właśnie napotkałem tę sytuację... Niezbyt przyjemne doświadczenie.
W jednym z moich plików c
:
void unused_isr(void) {}
void ADC_IRQHandler(void) __attribute__ ((weak, alias("unused_isr")));
Następny gdzieś w pliku cpp
zdefiniowałem:
void ADC_IRQHandler(void) {
...
}
I zapomniałem zmienić deklarację forward na:
void ADC_IRQHandler(void);
Zajęło mi trochę czasu zanim zorientowałem się, że robię wszystko dobrze w odniesieniu do konwersji reklam, ale nie dodałem "extern C" do definicji!
extern "C" void ADC_IRQHandler(void) {
...
}
Tylko moje dwa grosze, dlaczego może się przydać w pewne okoliczności, aby mieć zwyczaj, aby dodać go do definicji, jak również.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-07 09:21:42
Myślę, że należy to tutaj wyjaśnić, ponieważ właśnie miałem podobny problem i zajęło mi trochę czasu, aby to wyjaśnić w mojej głowie, tylko Brooks Moses poruszył to właściwie i myślę, że należy to powiedzieć jaśniej ...
Podsumowując nagłówek może cię wyrzucić, kompilator widzi tylko plik cpp i jeśli nagłówek nie jest dołączony z extern "C" z powrotem do twojego cpp (co zwykle widzę), to extern "C" będzie musiał być gdzieś w pliku cpp (albo w pliku cpp). definition, or another declaration) więc kompilator CXX może wiedzieć, aby zrobić to z C linkage, kompilator nie dba o nagłówek, tylko linker.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 04:04:03
extern "C"
wokół definicji nie jest wymagane. Możesz ujść na sucho po prostu umieszczając to wokół deklaracji. Jedna uwaga w twoim przykładzie...
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
Twój kod szuka makra preprocesora " __cplusplus
".
Chociaż jest powszechnie zaimplementowany, w zależności od kompilatora, może to być zdefiniowane lub nie. W twoim przykładzie używasz również extern "C"
wokół deklaracji, ale tam nie sprawdzasz pod kątem makra " __cplusplus
", dlatego podejrzewam, że zadziałało raz ty to zrobiłeś.
zobacz poniższe komentarze - standard C++ wymaga zdefiniowania makra __cplusplus
przez preprocesor.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-04 05:03:38
Powinno być w pobliżu obu. Kompilator musi wiedzieć, aby używać nazwy symbolu C i wywoływać konwencje podczas kompilacji witryn wywołujących (które mogą widzieć tylko deklarację), a kompilator musi również wiedzieć, aby generować nazwę symbolu C i używać konwencji wywołujących C podczas kompilacji samej definicji funkcji (która może nie widzieć żadnych innych deklaracji).
Teraz, jeśli masz deklarację extern-C, która jest widoczna z jednostki tłumaczenia, w której istnieje definicja, możesz być w stanie ujść na sucho z pominięciem extern-C z definicji, ale nie wiem tego na pewno.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-04 18:32:30