Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12

Discussione: A che serve __cdecl?

  1. #1
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157

    A che serve __cdecl?

    Salve.

    Sul sito MSDN ho trovato la parolina chiave __cdecl (che dovrebbe appartenere solo a Visual Studio se non erro). E si utilizza in questo modo, ad esempio:

    void __cdecl funzione()
    {
    ...
    }

    Qual'è la sua funzionalità? (Francamente su MSDN non ci ho capito una mazza... come al solito...) Insieme a __cdecl era citato anche __stdcall.

    http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.80).aspx

    Qualuno sarebbe così gentile da spiegarmi tutto per filo e per segno? Grazie mille.

  2. #2
    Specifica la convenzione di chiamata cdecl; le altre disponibili sono stdcall, fastcall e thiscall (quest'ultima è l'unica impiegabile per i metodi delle classi).
    Una convenzione di chiamata (calling convention) specifica come vengono passati i parametri e il valore restituito tra procedura chiamante e chiamata; a seconda della convenzione di chiamata, ad esempio, i parametri sono passati sullo stack in un certo ordine (da sinistra a destra o da destra a sinistra), alcuni possono essere passati nei registri della CPU, possono essere passati parametri aggiuntivi impliciti (come nel caso di thiscall, in cui il puntatore all'oggetto this è sempre passato implicitamente in modo che il metodo possa accedere ai membri dell'oggetto su cui è stato chiamato), la responsabilità di pulire lo stack viene affidata alla funzione chiamante o a quella chiamata.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Grazie.

    Quindi, se ho capito bene, servono a indicare come devono essere chiamate le funzioni. Non ho però compreso il perché usare cdecl piuttosto che stdcall piuttosto che non scrivere nulla, ecc... Saresti così gentile da spiegarmi in particolare quale sia la differenza sostanziale, per una funzione generica void funz(), di tutte le possibilità? Ad esempio:

    codice:
    void funz() {...}
    codice:
    void __cdecl funz() {...}
    codice:
    void __stdcall funz() {...}

  4. #4
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,563
    Se non scrivi niente mi pare è implicitamente specificato __cdecl

    Le differenze le trovi qui
    http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.80).aspx
    e qui
    http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.80).aspx
    http://msdn.microsoft.com/en-us/library/6xa169sk(VS.80).aspx
    "Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)

    "Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)

    http://xvincentx.netsons.org/programBlog

  5. #5
    • cdecl passa i parametri sullo stack in ordine inverso; consente di creare funzioni che accettano un numero variabile di parametri (come printf, per esempio), ma la chiamata di una funzione cdecl genera più codice macchina rispetto ad una chiamata a funzioni con altre convenzioni di chiamata; questo perché cdecl specifica che dev'essere il chiamante a ripulire lo stack dai parametri, per cui per ogni chiamata ci deve essere il codice di passaggio dei parametri (una serie di push di parametri sullo stack), la chiamata vera e propria (call) e la pulitura dello stack (una serie di pop). È proprio il fatto che è il chiamante a ripulire lo stack a rendere possibile la chiamata con numero variabile di argomenti: infatti il codice chiamato non ha idea di quanti parametri in più ci siano e quanto spazio occupino sullo stack, per cui non ha informazioni su come pulire lo stack;
    • stdcall è la convenzione di chiamata più diffusa nelle dll e in generale nel codice che dev'essere chiamato da applicazioni esterne; i parametri sono passati sullo stack in ordine inverso, ma la responsabilità di ripulire lo stack spetta alla funzione chiamata. In questa maniera il codice di pulitura dello stack può essere messo in coda al codice della funzione invece di essere ripetuto al termine di ogni chiamata alla funzione, per cui, a parità di codice, un eseguibile in cui le funzioni sono stdcall risulterà tendenzialmente più piccolo di uno in cui le funzioni sono cdecl;
    • fastcall è una convenzione di chiamata non standardizzata e viene usata di solito solo all'interno delle applicazioni (non in codice richiamabile dall'esterno); i primi due parametri vengono passati, se possibile, nei registri ECX e EDC; gli altri vengono messi sullo stack in ordine inverso. Anche qui la responsabilità di pulire lo stack spetta alla funzione chiamata. Rispetto a stdcall e cdecl dovrebbe essere più veloce passare i primi due parametri e accedervici, perché si trovano nei registri invece che sullo stack.
    • thiscall è una convenzione di chiamata "speciale", che viene impiegata nei metodi delle classi che non usano un numero variabile di parametri; è analoga a stdcall, ma il puntatore a this (ossia all'oggetto su cui è stato invocato il metodo in questione) viene passato nel registro ECX. Nel caso di metodi con numero variabile di argomenti invece si ricorre a cdecl, piazzando this per ultimo sullo stack.

    All'atto pratico io di solito uso fastcall come convenzione di chiamata predefinita (tramite l'opzione /Gr del compilatore) e stdcall per le funzioni richiamate dall'esterno (callback, funzioni esportate, ...); per forza di cose uso thiscall per i metodi delle classi. Se scrivessi funzioni con numero di argomenti variabile dovrei necessariamente usare per loro cdecl, ma il problema non si pone visto che non ricorro mai a questa funzionalità.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da XWolverineX
    Le differenze le trovi qui
    http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.80).aspx
    http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.80).aspx
    http://msdn.microsoft.com/en-us/library/6xa169sk(VS.80).aspx
    Denghiu.

    Sei sicuro che non specificando alcunché, utilizzi automaticamente __cdecl?

    Nella documentazione ho trovato degli esempi in cui mi sembra ci sia una contraddizione (ovviamente non sarà così), però...

    In __cdecl trovo:

    codice:
    void CMyClass::mymethod() { return; }
    is equivalent to this:
    codice:
    void __cdecl CMyClass::mymethod() { return; }
    In __stdcall trovo:

    codice:
    void CMyClass::mymethod() { return; }
    is equivalent to this:
    codice:
    void __stdcall CMyClass::mymethod() { return; }
    Chi ha ragione?

  7. #7
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da MItaly
    cdecl passa i parametri ...
    Denghiu veri veri mach

  8. #8
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,563
    Originariamente inviato da xshell
    Denghiu.

    Sei sicuro che non specificando alcunché, utilizzi automaticamente __cdecl?

    Nella documentazione ho trovato degli esempi in cui mi sembra ci sia una contraddizione (ovviamente non sarà così), però...

    In __cdecl trovo:

    codice:
    void CMyClass::mymethod() { return; }
    is equivalent to this:
    codice:
    void __cdecl CMyClass::mymethod() { return; }
    In __stdcall trovo:

    codice:
    void CMyClass::mymethod() { return; }
    is equivalent to this:
    codice:
    void __stdcall CMyClass::mymethod() { return; }
    Chi ha ragione?
    Dipende dall'opzione specificata nel compilatore
    "Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)

    "Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)

    http://xvincentx.netsons.org/programBlog

  9. #9
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da XWolverineX
    Dipende dall'opzione specificata nel compilatore
    Ehm... e come si specifica in Visual Studio?

  10. #10
    Nelle proprietà del progetto, sotto "convenzione di chiamata predefinita" (o qualcosa del genere). Comunque che io sappia per i membri delle classi o si usa thiscall o cdecl, non ci sono altre alternative.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.