Newsgroup: it.comp.lang.c++
Titolo: Convenzioni di chiamata e funzioni extern"C"

Che convenzione di chiamata è adottata nel C++? (Se volessi scrivere una
funzione in ASM da usare col C++...)
Inoltre, se nella definizione di una funzione C++ indico che deve essere
extern "C", per poterla chiamare col C, nel blocco della funzione posso
usare qualsiasi caratteristica del C++, mentre come parametri e valore
restituito posso usare solo i tipi ammessi dal C per valore e tramite
puntatore, vero?
--
Marco Iannaccone     
marc...@tin.it
ICQ: 18748121           Tolkien
"I've... seen things you people wouldn't believe. Attack ships on fire off
the shoulder of Orion.
I watched C-beams... glitter in the dark near the Tanhauser Gate. All
those... moments will be lost... in time..., like... tears... in... rain."
FAQ it.comp.lang.c: 
http://www.programmazione.it/linguaggi/c/itcomplangc.htm
FAQ it.comp.lang.c++: 
http://www.programmazione.it/linguaggi/c/lang_faq.htm

 puntatore, vero?
Mi sa che hai fatto un po' di confusione. La dichiarazione extern "C"
serve ad utilizzare in C++ funzioni scritte in C e non viceversa.
EMG

 serve ad utilizzare in C++ funzioni scritte in C e non viceversa.
No, nel Petzol c'e scritto che se metto extern "C" davanti la dichiarazione
di una funzione, magari in un header, serve per comunicare al compilatore
che quella funzione è stata scritta in C, ma dice anche se se nella
DEFINIZIONE di una funzione antepongo extern "c", indico al compilatore di
compilarla in modo che sia utilizzabile anche dal C, e infatti nella
documentazione delle DirectX, che sono scritte in C, alla definizione di una
funzione per caricare una bitmap il una superficie DirectX è anteposto
extern "C" (e in fatti le DirectX, con un po di fatica, sono utilizzabili
anche col C...)
Comunque, che convenzione di chiamata è usata?


 ha scritto nel messaggio
news:8pvmnj$400$1...@nslave1.tin.it...


 compilarla in modo che sia utilizzabile anche dal C,
Ah, ecco. Questo non lo sapevo. Quindi si sta parlando di funzioni
ancora da compilare e non di librerie (codice quindi già compilato) come
pensavo io. Non capisco però come faccia a funzionare ancora
l'overloading. Secondo me questo inusuale utilizzo della dichiarazione
extern "C" deve avere forti limitazioni.
EMG

 extern "C" deve avere forti limitazioni.
E infattio volevo conoscere proprio queste limitazioni, dato che Lippmann
non ne parla...


 > pensavo io.
Credo ti stai sbagliando.
extern "C" indica che la funzione usa le convensioni di chiamata
del C.
extern "C" si applica alla 'dichiarazione' della funzione (che č
definita in qualche modulo oggetto).
Dichiari che quella funzione usa le convensioni di chiamata
del C.
Manlio Perillo

 del C.
A me non sembra sia cosě. Mi pare che extern "C" indichi al compilatore
di non cercare le funzioni in essa incluse con il loro nome decorato ma
con quello nudo e crudo. Questo fa si che anche una funzione compilata
con un compilatore C, e quindi presente nella libreria con il suo nome
non decorato, possa essere regolarmente chiamata da un compilatore C++.
EMG

 A me non sembra sia così. Mi pare che extern "C" indichi al compilatore


convenzioni di chiamata C, 
"Use extern "c" to prevent function names from being mangled in C++
programs."
Si usa extern "C", per evitare il mangling dei nomi nelle compilazioni
di codice C++.
--
Andrea Laforgia (UIN 87230455)
----------------------------------------------------------
Non scrivetemi per e-mail, se non richiesto espressamente.
No replies in private e-mail, unless explicitly requested.
----------------------------------------------------------

 Manlio Perillo
credo ti stia sbagliando tu... extern "C" indica che eviti la decorazione
dei nomi delle funzioni che vengono usate dal compilatore per risolvere le
funzioni con l'overloading. La convenzione di chiamata č un'altra cosa,
infatti puoi ben scrivere
extern "C" __cdecl ...
extern "C" __fastcall ...
extern "C" __stdcall ...
e avrai le rispettive convenzioni di chiamata. Per questo motivo,
l'overloading non funziona pių, come arguiva giustamente EMG.

     LPCSTR szBitmap, int dx, int dy)
Per quanto ne so io, l'effetto di quanto sopra è che il nome della
funzione DDLoadBitmap() non viene alterato compilando con un compilatore
C++. In mancanza della extern "C" invece il nome sarebbe modificato in
qualcosa tipo DDLoadBitmap_IDirectDrawptr_szBitmap_int_int().
EMG

una delle solite estensioni della MS?
A detta di B.Stroustrup (cito sempre lui, ma è la fonte più autorevole che
ho a riguardo) il C++ ha spesso convenzioni di chiamata di funzione +
efficienti di quelle del C. La p.chiave "extern" indica quindi al
compilatore di trattare "in generale" (nomi, chiamata ecc ecc ecc) una
funzione come funzione C.
Ciao
Domenico

l'overloading non funziona più, come arguiva giustamente EMG.
1)  __cdecl = __fastcall = __stdcall = NON_STANDARD
2) L'overloading non funziona perchè IL C (che è il linguaggio che viene a
questo punto utilizzato) NON PERMETTE L'OVERLOAD.
3) Ti assicuro che esistono compilatori ai quali la parola "extern" indica
convenzioni di chiamata diverse (in genere meno efficienti).
Ciao
Domenico Barra


Nel draft dello Standard c'è il seguente esempio
namespace A {
  extern "C" int f();
  extern "C" int g() { return 1; }
  extern "C" int h();
}
namespace B {
  extern "C" int f();
  // A::f and B::f refer
  // to the same function
  extern "C" int g() { return 1; }
  // ill-formed, the function g
  // with C language linkage
  // has two definitions
}
Comunque lo Stroustrup dice che:
"For example, different languages and different implementations
of the same language may differ in their use of machine registers
to hold arguments, the layout of arguments put on stack, the
layout of builtins types such as strings and integers, the form
of names passed by compiler to the linker, and the amount of
type checking required from the linker.
To help, one can specify a linkage convention to be used in
an extern declaration.
....
The extern "C" directive is particularly useful because of the
close relationship between C and C++.
Note that the C in extern "C" names a linkage convention and not
a language. Often, extern "C" is used to link Fortran and
assembler routines that happen to conform to the conventions of
a C implementation."
Alla fine credo che avevamo ragione entrambi
(sempre che lo Stroustrup abbia ragione, a volte dice cose
 che possono dare luogo ad ambiguità).
Manlio Perillo

 che possono dare luogo ad ambiguità).
Ehm..., considerando che il linguaggio l'ha inventato lui e che e' a
capo del comitato di standardizzazione, tenderei a dargli credito ;)


 passato alla funzione e del nome della funzione.
Serve per supportare cose tipo overload di funzioni, o funzioni menro,
etc...?





etc...?
Serve in assoluto per assicurare lo "strong-type checking" (risposta
alla tua domanda = si'), di cui il C e' privo, ma di cui il C++ si fa
pieno carico.


no?
Non solo. Come gia' detto, serve a controllare che i nomi non vengano
decorati.


 Alla fine credo che avevamo ragione entrambi
Forse. Ma è certo che con voi si imparano cose nuove ad ogni messaggio.
Grazie veramente a tutti.
EMG

 no?
Il linguaggio (ne' il C ne' il C++) NON prescrive il modo in cui i
parametri formali vengono passati ad una procedura; questo modo e'
implementation-dependent.  E' quindi il compilatore a sceglierlo;
anche se l'architettura della CPU puo' condizionare in maniera piu' o
meno rigida tale modo.
E' perfettamente compatibile con gli standard il caso in cui due
compilatori differenti scelgano metodi differenti di passaggio dei
parametri formali; ed in cui oggetti compilati dal primo non possano
quindi essere linkati con oggetti compilati dal secondo.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

1)  __cdecl = __fastcall = __stdcall = NON_STANDARD
2) L'overloading non funziona perchè IL C (che è il linguaggio che viene a
questo punto utilizzato) NON PERMETTE L'OVERLOAD.
beh, io non ho mica detto il contrario. Sono assolutamente d'accordo con te!
3) Ti assicuro che esistono compilatori ai quali la parola "extern" indica
convenzioni di chiamata diverse (in genere meno efficienti).
quali? su quelli che ho provato io extern "C" indica le stesse convenzioni
di chiamate stabilite per le altre funzioni, per variarle si usano quei
parametri che ho indicato. Non pretendo che questo sia un comportamento
standard, ma sono quasi assolutamente sicuro che extern "c" non indichi la
convenzione di chiamata da stabilire, ma solamente il fatto di trattare una
funzione dichiarata in tale maniera come una funzione scritta in C (con quel
che ne segue).
--
Posted from 
venus.record.unipd.it
 [147.162.163.2] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

che ne segue).
Quasi. Attenzione al fatto che il "C" di extern non vuol dire
"linguaggio C". 


"linguaggio C".
Già, su questo siamo perfettamente d'accordo ;-)
Ciao
Domenico


 __fastcall e' qualcosa di ancora diverso. Vabbe', siamo OT ;)
come non sono la stessa cosa? sono tutte specificazioni sulla convenzione di
chiamata. So che non sono standard, e sul tuo compilatore potrebbe indicare
il meccanismo con cui ti devono fuoriuscire i demoni dal naso, ma da me č
cosě ;)


 convenzione di collegamento...
siamo sicuri che la convenzione di collegamento e la convenzione di chiamata
siano effettivamente sinonimi? la convenzione di chiamata indica se e come i
parametri devono essere passati sullo stack e se il compilatore deve o non
deve ripristinare lo stack pointer successivamente... da me ;)


deve ripristinare lo stack pointer successivamente... da me ;)
Già, non sono sinonimi, ma hai letto la seconda parte (per intenderci, da "e
prima ancora..." in poi?
Ciao
Domenico


già, scusa... ero di fretta e quel pezzo non l'ho letto.
se la mette così BS allora non discuto... quel pezzo sinceramente non
l'avevo mai letto.

chiamata.
Ma questo non vuol dire che indichino la "stessa"  convenzione di
chiamata. Ci sono delle sottili/grandi differenze tra l'una e l'altra.


Già, in C non indica alcuna convenzione di chiamata, ma parliamo del C++
In C++ cosi' come in C, la parola chiave 'extern' NON indica ALCUNA
convenzione di chiamata.
E' 'extern "C"' ad indicare il modo in cui dovra' essere trattato cio'
che segue.


che segue.
Lo so, ed è proprio quello di cui stiamo parlando. Leggi il mio messaggio
del 20 settembre, dove cito B.Stroustrup.
Ciao
Domenico

del 20 settembre, dove cito B.Stroustrup.
"Ti assicuro che esistono compilatori ai quali la parola "extern"
indica convenzioni di chiamata diverse (in genere meno efficienti)."
E' questo quello a cui mi riferisco.


E' questo quello a cui mi riferisco.
Già, scusami, intendevo extern "Language" (che può essere extern "C", o
laddove il compilatore lo permetta, extern "COBOL" ...).
Sì, ho sbagliato io a scrivere, volevo dire extern "C".
Ciao ;-)
Domenico

Sì, ho sbagliato io a scrivere, volevo dire extern "C".
Aridaglie ! LA "C" di extern NON indica alcun linguaggio !
E' la convenzione di TIPO C. Non esiste alcun extern "COBOL" !
--
Andrea Laforgia (ICQ 87230455)

E' la convenzione di TIPO C. Non esiste alcun extern "COBOL" !
Nella stringa dopo extern di solito c'è "C" perché è solo quello che è
supportato dalla stragrande maggioranza dei compilatori (e serve a rendere
compatibile codice C con C++); convenzione di tipo C significa "chiama le
funzioni e passa le variabili come se si trattasse di C, non di C++". E'
questo il motivo per cui si potrebbe ipoteticamente scrivere extern "COBOL"
(anche se hai ragione a dire che non esiste, perché nessun compilatore che
io conosca supporta tale tipo di collegamento)
Ciao
Domenico

questo il motivo per cui si potrebbe ipoteticamente scrivere extern "COBOL"
Assolutamente no.
"C" non indica "Linguaggio C".


 chiamata. Ci sono delle sottili/grandi differenze tra l'una e l'altra.
intendi dire differenze tra, per esempio, la stessa __stdcall da un
compilatore all'altro o tra __stdcall e __fastcall (sempre per esempio) di
uno stesso compilatore? nel primo caso, beh, senz'altro... anche xchè se no
sarebbero standard ;-P... nel secondo invece è abbastanza ovvio

uno stesso compilatore? 
Entrambi i casi.
Il secondo caso non mi sembra cosi' ovvio, comunque la trattazione
delle differenza tra le diverse keyword non standard e' ot qui dentro.


"C" non indica "Linguaggio C".
Vedi sopra.
Ciao
Domenico
PS: non c'è motivo di spazientirsi, io la prendo come amichevole (e molto
costruttiva) discussione. Ciao ;-)

IMPLEMETAZIONE C [e come vedi c'è sempre il C di mezzo]. "
Leggi attentamente... Bjarne Stroustrup nello stesso testo ci tiene a
precisare che la "C" in questione NON E' LA STESSA "C" DI "LINGUAGGIO
C". Pare che tu abbia "sorvolato" su questo particolare ;)


C". Pare che tu abbia "sorvolato" su questo particolare ;)
Sinceramente non ho trovato il passo a cui fai riferimento (mi fido, c'è di
sicuro), ma, per quanto "C" c'entri poco effettivamente col C, è proprio
collegamento e convenzioni di chiamata del C che indica (attenzione, non
dico linguaggio, dico collegamento e chiamata...). Sei d'accordo con me
adesso?
Ciao
Domenico

collegamento e convenzioni di chiamata del C che indica 
No, solo collegamento.
Non influisce sulle modalita' di chiamata.
Una funzione C usata da C++ subisce i controlli piu' rigorosi del C++.
--
Andrea Laforgia (ICQ 87230455)
------------------------------ 
#exclude <windows.h>

Una funzione C usata da C++ subisce i controlli piu' rigorosi del C++.
D'accordo, e anche Stroustrup lo ribadisce, usando la stessa tua frase, ma
dice che il passaggio di parametri sullo stack e altre convenzioni possono
differire con la convenzione extern "C"
Ciao
Domenico

differire con la convenzione extern "C"
Il passaggio dei parametri sullo stack e' una caratteristica
"implementation-dependant". Non si puo' affermare che ve ne sia una
per il C++ ed una per il C, distinte.


per il C++ ed una per il C, distinte.
Sì, ma credo che la direttiva 'extern "C"' elimini ogni possibile ambiguità.
Domenico

EUREKAA! Ho trovato!!!
Incuriosito dall'assenza, nella libstdc++ di gcc, degli 'stringstream's
(file: sstream), ho trovato, nel file '\usr\include\g++-3\strstream.h'
l'istruzione ' extern "C++" ' !!!!!!
Quindi non c'è solo la convenzione C, ma anche quella C++ ...
Domenico