Προς το περιεχόμενο

Naming Conventions C++


Evgenios1

Προτεινόμενες αναρτήσεις

Δημοσ.

Μια απλη απορια. Για ποιο λογο να μην γραψουμε ενα προγραμμα το οποιο θα ειναι απο __stdcall και οχι απο __cdecl ?

Απο το παρακατω βλεπω οτι το γρηγοροτερο ειναι το standar call.

Υγ: διαβασα οτι το esp esi τσεκαρουν κατι... αλλα δε βρηκα τι

>	 FastCall(1);
0041371E  mov         ecx,1 
00413723  call        FastCall (411190h) 
 defaultCall(1);
00413728  push        1    
0041372A  call        defaultCall (4110D2h) 
0041372F  add         esp,4 
 stdCall(1);
00413732  push        1    
00413734  call        stdCall (4111B3h) 

Δημοσ.

το stdcall ήταν απο την pascal οπου δεν υπήρχαν var_arg (μεταβλητός αριθμός παραμέτρων).

Το cdecl λύνει αυτό ακριβώς (και μόνο αυτό) το πρόβλημα και έτσι έχουμε τη δυνατότητα των var_args.

Το μόνο μειονέκτημα του cdecl είναι η επιβάρυνση κάποιων εντολών για cleanup stack μετά απο κάθε call συνάρτησεις (τρίχες δηλαδή!)

 

ή καλυτερα __fastcall
την κολοκυθιά θα παίζουμε;:mrgreen::lol:
Δημοσ.
το stdcall ήταν απο την pascal οπου δεν υπήρχαν var_arg (μεταβλητός αριθμός παραμέτρων).

Το cdecl λύνει αυτό ακριβώς (και μόνο αυτό) το πρόβλημα και έτσι έχουμε τη δυνατότητα των var_args.

Το μόνο μειονέκτημα του cdecl είναι η επιβάρυνση κάποιων εντολών για cleanup stack μετά απο κάθε call συνάρτησεις (τρίχες δηλαδή!)

 

την κολοκυθιά θα παίζουμε;:mrgreen::lol:

 

Δεν έχει σχέση το stdcall και το cdecl mε var_arg. Η (κύρια) διαφορά τους είναι ποιος καθαρίζει την στοίβα αφού εκτελεστεί η συνάρτηση.

Στο stdcall την στοίβα καθαρίζει η κληθείσα συνάρτηση ενώ σε cdecl η καλούσα. Τελικά η ίδια εντολή τρέχει (αυξάνατε ο stack pointer - esp : είπαμε η στοίβα μεγαλώνει προς τις μικρές διευθύνσεις)

 

Επίσης το fastcall έχει αρκετή διαφορά σε ταχύτητα αφού ελαττώνει κατά το δυνατό την πρόσβαση στη μνήμη για τις παραμέτρους, αν και οι υλοποιήσεις διαφέρουν. Αυτό γίνεται γιατί όσες παράμετροι μπορούν, αντί να γίνουν push στην στοίβα, μπαίνουν σε registers. Οπότε εκτός ότι γλιτώνεις την ανάγνωση / εγγραφή στη RAM, γλιτώνεις (σε κάποιες περιπτώσεις) και τις εγγραφές-διαγραφές στην στοίβα.

 

Εν ολίγοις το πιο γρήγορο και πιο ασύμβατο είναι το fastcall (δεν υπάρχει standard για την υλοποίηση). Αυτά περί ταχύτητας εννοείται ότι τα παρατηρείς όταν γίνονται (πάρα) πολλά calls σε μια συνάρτηση και όχι καλώντας την μια και δυο φορές. Ιδιαίτερα με τα σημερινά CPU όπου η συχνότητα του επεξεργαστή σε σχέση με αυτή της RAM διαφέρει τάξεις μεγέθους, μια μικρή συνάρτηση αν χρησιμοποιεί μόνο registers για την εκτέλεση θα εκτελείται δεκάδες φορές πιο γρήγορα.

Δημοσ.
Δεν έχει σχέση το stdcall και το cdecl mε var_arg. Η (κύρια)

 

http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx

 

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

 

The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack, so the compiler makes vararg functions __cdecl.

 

This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions

 

αν δεν έχει σχέση, τότε κάνε stdcall με συναρτηση var_arg και να δουμε τι general protection fault θα πάρεις. Δηλαδή η συνάρτηση με stdcall θα ξέρει τι να βγάλει απο το stack;

αν δεν υπήρχαν τα var_args θα είχαν ασχοληθεί να φτιάξουν το cdecl; Γιατί, για να ξαναεφευρουν τον τροχό;

-------

Τα fastcall όπως και τα register variables, είναι πρόταση προς τον compiler που αν θέλει και μπορεί την χρησιμοποιεί. Γι'αυτο δεν επεκτάθηκα στο θέμα αν θα μπορούσαν να γίνουν standard.

Δημοσ.

Ομολογώ πως δεν το ήξερα. Τώρα που το ξανασκέφτομαι βλέπω την διαφορά. Ο κώδικας της κάθε συνάρτησης δεν μπορεί να αλλάζει άρα πρέπει ο caller να καθαρίζει τον μεταβλητό αριθμό push που έκανε πριν καλέσει την συνάρτηση. Έχεις δίκιο. Βιάστηκα να το πω γιατί θεωρούσα πως ήταν απλά ένα array, αλλά αυτό δεν γίνεται γιατί δεν δηλώνεις (αναγκαστικά) τις μεταβλητές με την σειρά που θα τις περάσεις παράμετρο.

Δημοσ.

και σ'αυτό που είπε ο Ευγένιος για τις printf/scanf ... μπορεί τωρα να είναι λίγες οι va_arg συναρτησεις, αλλα στην εποχη των K&R ήταν ΟΛΕΣ οι συναρτησεις "έτσι".

 

Τότε δεν χρειαζόταν να τις δηλώσεις πριν τις καλέσεις, οπότε ο compiler δεν ήξερε όταν τις καλούσε πόσα arguments θέλαν και αν ηταν τυχερός ο προγραμματιστής και θυμόταν το σωστό αριθμό απο arguments είχε καλώς, αλλιως μπορεί να έπερνε και σαβούρες η συνάρτηση. Αλλά τουλάχιστον δεν θα κατέστρεφε τον stack pointer.

 

Τότε δημιουργήθηκε η ανάγκη για να διαγράφει ο caller τις παραμέτρους απο το stack.

 

πάντως είναι απο τις πληροφορίες που δεν χάνεις και πολλά αν δεν τις ξέρεις:mrgreen:

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...