pointer-to-object casting και ISO C++

Πιστιόλης Κωνσταντίνος pistiolis at ts.sch.gr
Wed Mar 1 08:34:37 EET 2006


Την Wed, 01 Mar 2006 04:03:19 +0200,ο(η) Eustathios Kamperis  
<ekamperi at auth.gr> έγραψε/wrote:

> Καλημέρα σε όλους!
>
> Θεωρήστε το εξής κομμάτι κώδικα:
>
> void foo(const void *pf) {
>   cout << "Function address: " << pf << endl;
> }
>
> void tralala() {
> }
>
> foo((void *) &tralala);
>
> Αν κάνω compile με την παράμετρο -pedantic, ο compiler παραπονείται για
> το εξής:
> "warning: ISO C++ forbids casting between pointer-to-function and
> pointer-to-object"
>
> Αν παραλείψω την παράμετρο -pedantic, το πρόγραμμα μεταγλωττίζεται και
> εκτελείται σωστά.
>
> Γνωρίζετε κάποιο τρόπο *συνεπή* με το πρότυπο της C++ κατά ISO για να
> περνάω στη foo() τη διεύθυνση της tralala(). Αν όχι, έχετε να μου
> προτείνετε κάποια εναλλακτική προσέγγιση στο όλο θέμα;
Δεν είναι καλή προσέγγιση να μετατρέπεις κάτι σε void * για να το
περάσεις σε μια συνάρτηση. Δεν ξέρω τι θέλεις να κάνεις, αλλά στις
περισσότερες περιπτώσεις δεν υπάρχει λόγος να απενεργοποιείς τους
ελέγχους τύπων της C. Και καλά να μετατρέψεις δεδομένα. Άντε το
int * είναι μια θέση στη μνήμη όπου αρχίζει ένας int, ενώ το void *
είναι μια θέση στη μνήμη όπου αρχίζει "κάτι" που εσύ ξέρεις τι είναι.
Αλλά η διεύθυνση μιας συνάρτησης είναι είναι ένα "κάτι" που πρέπει
να το χειριστείς με πολύ προσοχή για να μη σου κολλήσει, δηλαδή να
το μετατρέψεις ακριβώς σε αυτό που ήταν πριν το κάνεις void *.
Αν δεν το κάνεις σωστά μπορεί να δουλεύει τυχαία, ή μόνο γι αυτό
το μεταγλωττιστή.

Αυτό που θές είναι δείκτης σε μιά συνάρτηση όπως η tralala,
που να παίρνει δηλαδή 0 ορίσματα και να επιστρέφει void:
void (*)();
και η foo τέτοιο όρισμα πρέπει να παίρνει:
void foo(void (*)());              //πρωτότυπο
void foo(void (*funcPtr)()){...}   //ορισμός

Εναλλακτικά, μπορείς να δημιουργήσεις έναν τύπο, για να μη μπερδεύεσαι με  
όλα
αυτά.
typedef void (*MyFuncPtr)();

και μετά
void foo(MyFuncPtr);               //πρωτότυπο
void foo(MyFuncPtr funcPtr){...}   //ορισμός



Σημείωση: άλλο το void (*)() στη C κι άλλο στη C++. Στη C, σημαίνει ότι
"δεν προσδιορίζεις" τι ορίσματα παίρνει, που σημαίνει πως ό,τι και
να του δώσεις σαν όρισμα(-τα) είναι έγγυρο.
Εκεί γράψε void (*)(void) για μηδενικό αριθμό ορισμάτων






More information about the Linux-greek-users mailing list