migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 ... Με αυτή τη λογική ολόκληρο C++ standards committee είναι (δεν ξέρω τι θέλεις να τους πεις) γιατί έβαλαν στη γλώσσα το static_cast αφού υπάρχει το reinterpret_cast και μάλιστα δυό φορές γιατί έβαλαν και το reinterpret_cast ενώ υπάρχει το C-style cast που τα κάνει όλα και συμφέρει ("πιο ευέλικτο" για να χρησιμοποιήσω δικές σου λέξεις). Νομίζω δε χρειάζεται να γράψω περισσότερα. Αν δε σε προβληματίζει η παραπάνω παράγραφος δε θα σε προβληματίσει οτιδήποτε και να πω. Προφανώς δεν έπιασες το χιουμοριστικό χαρακτήρα (πείραγμα ήταν, σε εκείνο το ποστ που έγραφες enum όπως και να 'χει επειδή παρέχεται δωρεάν ). Στην επιτροπή της C++ έχω να πω ένα μεγάλο ευχαριστώ που μας δίνει περισσότερες επιλογές και άρα μεγαλύτερη ευελιξία για το που θα χρησιμοποιήσουμε τι και γιατί.
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Defacer.. δες και το 6.7.2.2. Ευτυχώς γιατί είχα αρχίσει να ψάχνω τα πρότυπα τώρα (δεν ξέρω τι λέει το 6.7.2.2, αλλά είμαι 99.99% σίγουρος πως είναι compiler specific το enum type... επίσης καλώς ή κακώς δεν έχω κι εμπιστοσύνη στις παραθέσεις που κάνει ο defacer, συνήθως τις... κόβει σε καίρια σημεία ) Για δώστε κάνα ολοκληρωμένο link.
defacer Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Όμως, όταν τρέχει ο χρόνος και το date της παράδοσης έρχεται... δεν θέλω να κάτσω να μάθω πώς και τι θα γίνει, εάν γίνει. Αν κάποιος καταλήξει σ' αυτό το επιχείρημα (καταλαβαίνω βέβαια πως το αναφέρεις ενδεικτικά) τότε με γειά του με χαρά του. Παρόλο που είναι ανθρώπινο να πεις "φοβάμαι να μπλέξω, θα κάνω αυτό που ξέρω", νομίζω θα συμφωνήσεις ότι βάσει των παραπάνω και αν δεν υπάρξουν νέες αποκαλύψεις τότε στην ουσία δεν ξέρεις τι είναι αυτό που πας να κάνεις αφού δε μπορείς να δώσεις ικανοποιητική απάντηση στο "int το ένα, int το άλλο, ποιά η διαφορά?". Εγώ λοιπόν πάντα μα πάντα πάντα έχω σα στόχο το να καταλαβαίνω ακριβώς τι κάνω. Πολλές φορές δεν πιάνω το στόχο λόγω έλλειψης χρόνου ή λόγω αδυναμίας μου να καταλάβω κάτι ή... ή, αλλά και πάλι θα προσπαθήσω να γυρίσω πίσω αργότερα. Αν αυτό ο migf1 θέλει να το βαφτίσει μπλε programming και να παρουσιάσει από την άλλη το κόκκινο programming σαν προτιμότερη επιλογή, με γεια του με χαρά του αλλά ας μη πάρει κι άλλους στο λαιμό του. Επίσης, εάν η μνήμη που έχεις είναι της τάξης μερικών kilo BITS και εάν, εν γένει, είναι αρκετά memory critical το project... νομίζω ότι το #define SIZE 0x01, εάν έχεις 200 γραμμές από #defines, μπορεί να "σώσει" λίγη μνήμη από ένα enum με sizeof = sizeof(int). Δε θα σου φέρω αντίρρηση για χάρη της αντίρρησης, αλλά αν δεν απατώμαι δεν είναι specified το αν τα macros καταναλώνουν static storage ή όχι. Μ' αυτό το δεδομένο θα σου πω ότι μπορεί να σώσει, αλλά μπορεί και να μη σώσει. Εσύ σαν προγραμματιστής αισθάνεσαι καλά με τον εαυτό σου κάνοντας κάτι που "μπορεί" να έχει αποτέλεσμα; Εγώ όχι.
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Ευτυχώς γιατί είχα αρχίσει να ψάχνω τα πρότυπα τώρα (δεν ξέρω τι λέει το 6.7.2.2, αλλά είμαι 99.99% σίγουρος πως είναι compiler specific το enum type... επίσης καλώς ή κακώς δεν έχω κι εμπιστοσύνη στις παραθέσεις που κάνει ο defacer, συνήθως τις... κόβει σε καίρια σημεία ) Για δώστε κάνα ολοκληρωμένο link. Οκ, βρήκα αυτό: http://c0x.coding-guidelines.com/6.7.2.2.html Λίγο scrolling προς τα κάτω και... 1447 Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. 1448 The choice of type is implementation-defined,108) but shall be capable of representing the values of all the members of the enumeration. Αναφέρεται βλέπω στην C0x αλλά βαριέμαι τώρα να ψάχνω, πρέπει να ισχύει και στην C99 (αλλιώς δεν θα το είχα εντυπώσει ) ... Αναφέρεται βλέπω στην C0x αλλά βαριέμαι τώρα να ψάχνω, πρέπει να ισχύει και στην C99 (αλλιώς δεν θα το είχα εντυπώσει ) Α καλά, ότι να ΄ναι είμαι... σημάδι πως τα 'παιξα και πρέπει να την κάνω (το C0x είναι η C99).
defacer Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Defacer.. δες και το 6.7.2.2. Βασικά το 6.5.2.2 που έγραψα είναι σε μια παλιά άθλια version του C90 που έχω. Στο C99 έχει αλλάξει η παράγραφος σε 6.7.2.2, κοιτώντας το τώρα βλέπω την 6.7.2.2/4: Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until after the } that terminates the list of enumerator declarations. Το οποίο σημαίνει ότι σε κάθε περίπτωση ένας conformant compiler είναι within its rights αν σου το κάνει char σε περίπτωση που δεν έχεις αρκετά μεγάλες τιμές μέσα, ή διαφορετικά μπορεί να σου το κάνει unsigned int επειδή έτσι γουστάρει ακόμα κι αν έχεις μόνο θετικές τιμές που χωράνε σε signed int. Επομένως όπως φαίνεται υπάρχει ενδεχόμενο να έχεις π.χ. conversion από uint σε int το οποίο δε θα είχες αν χρησιμοποιούσες macro. Δεκτό λοιπόν το επιχείρημα σε ακαδημαϊκό επίπεδο (σε πρακτικό επίπεδο δεν αισθάνομαι ικανός να εκφέρω expert opinion) κι ευχαριστώ για την αφορμή να το φρεσκάρω.
bokarinho Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 @defacer. > /* Allocate a new object of the given type */ #define NEW(type) ((type *) Malloc(sizeof(type))) ..... void* Malloc(size_t n) { void* new = malloc(n); if(new==NULL) FATAL_ERROR("Out of memory."); return new; } Πως σου φαίνεται; Αργό; Γρήγορο; Ευέλικτο; Χρήσιμο; Άχρηστο; Λιτό; Την γνώμη σου.
Timonkaipumpa Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Αν κάποιος καταλήξει σ' αυτό το επιχείρημα (καταλαβαίνω βέβαια πως το αναφέρεις ενδεικτικά) τότε με γειά του με χαρά του. Παρόλο που είναι ανθρώπινο να πεις "φοβάμαι να μπλέξω, θα κάνω αυτό που ξέρω", νομίζω θα συμφωνήσεις ότι βάσει των παραπάνω και αν δεν υπάρξουν νέες αποκαλύψεις τότε στην ουσία δεν ξέρεις τι είναι αυτό που πας να κάνεις αφού δε μπορείς να δώσεις ικανοποιητική απάντηση στο "int το ένα, int το άλλο, ποιά η διαφορά?". Εγώ λοιπόν πάντα μα πάντα πάντα έχω σα στόχο το να καταλαβαίνω ακριβώς τι κάνω. Πολλές φορές δεν πιάνω το στόχο λόγω έλλειψης χρόνου ή λόγω αδυναμίας μου να καταλάβω κάτι ή... ή, αλλά και πάλι θα προσπαθήσω να γυρίσω πίσω αργότερα. Αν αυτό ο migf1 θέλει να το βαφτίσει μπλε programming και να παρουσιάσει από την άλλη το κόκκινο programming σαν προτιμότερη επιλογή, με γεια του με χαρά του αλλά ας μη πάρει κι άλλους στο λαιμό του. Δεκτή η απάντησή σου. Όμως, νομίζω δεν κατάλαβες τι ακριβώς εννοούσα. Φυσικά και συμφωνώ στην συνεχόμενη εξέλιξη. Όμως, όταν φτάνει σε σημείο σε πολλά project τα εργαλεία να είναι hardware και vendor dependent, με διάφορα ωραία σε μερικά micro controllers (όπως 3 περιοχές μνήμης, όλες από το 0x0000), τότε το να γυρίσεις πίσω και να μάθεις είναι, νομίζω, όχι και τόσο ωφέλιμο. Γιατί δεν αφορά την ουσία της γλώσσας (ή των νοητικών μοντέλων που θα χρησιμοποιήσει κανείς) αλλά "παραξενιές" του vendor. Οπότε, δεν είναι θέμα να καταλάβει κανείς τι κάνει, αλλά ότι δεν υπάρχει χρόνος για να μαθαίνει κανείς τις παραξενιές της κάθε εταιρείας, του κάθε compiler και του κάθε linker (βέβαια, και εντελώς προσωπικά μιλώντας, αυτό το προωθώ και λίγο... πιστεύω ότι συμβάλει σε x platform κώδικα... όσο μπορεί να γίνει φυσικά, εντάσεις δεκτές ). Βασικά το 6.5.2.2 που έγραψα είναι σε μια παλιά άθλια version του C90 που έχω. Στο C99 έχει αλλάξει η παράγραφος σε 6.7.2.2, κοιτώντας το τώρα βλέπω την 6.7.2.2/4: Το οποίο σημαίνει ότι σε κάθε περίπτωση ένας conformant compiler είναι within its rights αν σου το κάνει char σε περίπτωση που δεν έχεις αρκετά μεγάλες τιμές μέσα, ή διαφορετικά μπορεί να σου το κάνει unsigned int επειδή έτσι γουστάρει ακόμα κι αν έχεις μόνο θετικές τιμές που χωράνε σε signed int. Επομένως όπως φαίνεται υπάρχει ενδεχόμενο να έχεις π.χ. conversion από uint σε int το οποίο δε θα είχες αν χρησιμοποιούσες macro. Δεκτό λοιπόν το επιχείρημα σε ακαδημαϊκό επίπεδο (σε πρακτικό επίπεδο δεν αισθάνομαι ικανός να εκφέρω expert opinion) κι ευχαριστώ για την αφορμή να το φρεσκάρω. Σκέψου τώρα, οι τιμές αυτές να είναι δεδομένα σε buffer. Π.χ., ID από εντολές, στοιχεία και ό,τι άλλο. Unsigned int με singed int... και η άλλη μεριά να περιμένει unsigned και να παίρνει signed. Ή, ακόμα καλύτερα, να μην ξέρεις εάν θα είναι int, char, signed ή unsigned. Εκεί, νομίζω αλλά και σύμφωνα με τα αποπάνω, το #define είναι μονόδρομος... εκτός και εάν θέλει κανείς να μάθει "απόξω" όλες τις παραξενιές του κάθε compiler. edit Μιλάω για embedded systems only.
bokarinho Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Αχρηστο. Στη c δεν θες cast > /* Copy to obj from src, using sizeof(obj). Note that obj is an lvalue but src is a pointer! */ #define COPY(obj, src) (void)memcpy(&(obj), (src), sizeof(obj)) Δεν διαφωνώ, το πνεύμα είναι αυτό που κρίνουμε, κοίτα μία ωραία copy που την χρησιμοποιώ γενικά σε διάφορα project, πόσο γρήγορα και ευκολότερα κάνεις την δουλειά σου.
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 > /* Copy to obj from src, using sizeof(obj). Note that obj is an lvalue but src is a pointer! */ #define COPY(obj, src) (void)memcpy(&(obj), (src), sizeof(obj)) Δεν διαφωνώ, το πνεύμα είναι αυτό που κρίνουμε, κοίτα μία ωραία copy που την χρησιμοποιώ γενικά σε διάφορα project, πόσο γρήγορα και ευκολότερα κάνεις την δουλειά σου. Αν θες να είσαι σίγουρος πως τρέχει παντού, τότε το cast στο malloc δεν πειράζει (http://c-faq.com/malloc/cast.html) αλλά φρόντιζε να κάνεις include και το πρότυπό του (stdlib): http://c-faq.com/mal...locnocast.html. Κανονικά όμως από ANSI και μετά δεν το χρειάζεσαι. Το COPY σου όμως εμένα δεν μου κάθεται και πολύ καλά, γιατί είναι ασυνεπές ως προς το data type των 2 ορισμάτων του, τα οποία λογικά περιμένει κανείς να έχουν το ίδιο data type. Αλλά το obj πρέπει να περαστεί dereferenced και το src ως δείκτης. Βασικά ειδικά για το συγκεκριμένο δεν βρίσκω κάποιον ιδιαίτερο λόγο να φτιάξεις macro αντί να χρησιμοποιείς απευθείας την memcpy()... έτσι κι αλλιώς κι αυτή void * τα έχει τα ορίσματά της, άρα είναι από τη φύση της generic. To συγκεκριμένο macro το παρα-βρίσκω επιρρεπές σε σφάλματα. Μια κάπως καλύτερη εκδοχή του θα μπορούσε να είναι κάτι σαν κι αυτό... > #define myCOPY( pObj, pSrc, /* size*/ ) memcpy( (pObj), (pSrc), /* size */ ) που τουλάχιστον είναι συνεπές ως προς το data type των 2 λογικά ομοειδών ορισμάτων του και τα ονόματά τους δίνουν κι ένα hint ότι περιμένει δείκτες και στα 2 ορίσματα, αλλά και πάλι δεν νομίζω πως έχει λόγο ύπαρξης. Ειδικά αν τα ορίσματα αναφέρονται σε πίνακες, οπότε εκεί πια μιλάμε για πολύ μεγάλο πρόβλημα αν δεν δώσουμε explicitly το size. EDIT: Βασικά generic και για δείκτες και για πίνακες χωρίς explicit size δεν γίνεται. Με explicit size γίνεται ίδιο με την memcpy(). EDIT2: Ξέχασα, και το NEW() σου έχει ένα θέμα... δεν λειτουργεί για δημιουργία δυναμικών πινάκων. Αν αλλάξεις το 'type' σε 'size' θα λειτουργεί και για πίνακες, με την προϋπόθεση πως θα το καλείς με το σωστό size
imitheos Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 (επεξεργασμένο) > /* Copy to obj from src, using sizeof(obj). Note that obj is an lvalue but src is a pointer! */ #define COPY(obj, src) (void)memcpy(&(obj), (src), sizeof(obj)) Δεν διαφωνώ, το πνεύμα είναι αυτό που κρίνουμε, κοίτα μία ωραία copy που την χρησιμοποιώ γενικά σε διάφορα project, πόσο γρήγορα και ευκολότερα κάνεις την δουλειά σου. Μόνο εγώ δεν βλέπω την ευκολία και σίγουρα την ωρεάδα της ? To συγκεκριμένο macro το παρα-βρίσκω επιρρεπές σε σφάλματα. Μια κάπως καλύτερη εκδοχή του θα μπορούσε να είναι κάτι σαν κι αυτό... > #define myCOPY( pObj, pSrc, /* size*/ ) memcpy( (pObj), (pSrc), /* size */ ) που τουλάχιστον είναι συνεπές ως προς το data type των 2 λογικά ομοειδών ορισμάτων του και τα ονόματά τους δίνουν κι ένα hint ότι περιμένει δείκτες και στα 2 ορίσματα, αλλά και πάλι δεν νομίζω πως έχει λόγο ύπαρξης. Ειδικά αν τα ορίσματα αναφέρονται σε πίνακες, οπότε εκεί πια μιλάμε για πολύ μεγάλο πρόβλημα αν δεν δώσουμε explicitly το size. Για όνομα της $DEITY ρε παιδιά. Γιατί να μην τρέξετε κατευθείαν memcpy ? Η λέξη "memcpy" δεν παραπέμπει σε "copy" δηλαδή ? Τι θα κερδίσετε με το παραπάνω "alias" (γιατί δεν βλέπω να κάνει κάτι άλλο) ? Μου θυμίσατε αυτούς που έγραφαν aliases τύπου > #define BEGIN { #define END } γιατί λέει συνήθισαν σε pascal και τους φαίνεται πιο εύκολο Επεξ/σία 3 Ιουλίου 2012 από imitheos
Directx Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 [..]Από περιέργεια, για δοκίμασε να κάνεις #define μια τιμή που αντιστοιχεί ας πούμε σε 8 bytes. Λοιπόν, το enum στον συγκεκριμένο compiler φτάνει ως *DWORD οπότε ως εκεί τόσο το #DEFINE όσο και το ανάλογο enum επιστρέφουν σε dis-assembly όμοιο κώδικα σαν δοκιμάσεις να χρησιμοποιήσεις την τιμή που αναπαριστούν (αυτά όταν μεταφράζω με τον compiler ρυθμισμένο σε C). * Για την ιστορία, φυσικά μπορείς να υποχρεώσεις τον compiler να αντιμετωπίζει κάθε enum πάντα ως DWORD, η τυπική συμπεριφορά του όμως είναι η αυτόματη προσαρμογή του enum με βάση τις τιμές που περιλαμβάνει (ξεκινώντας από (un)signed char και φτάνοντας ως DWORD). Υ.Γ. Με την πρώτη ευκαιρία θα δω τι παίζει (από περιέργεια) και στην VC++
bokarinho Δημοσ. 3 Ιουλίου 2012 Δημοσ. 3 Ιουλίου 2012 Αν θες να είσαι σίγουρος πως τρέχει παντού, τότε το cast στο malloc δεν πειράζει (http://c-faq.com/malloc/cast.html) αλλά φρόντιζε να κάνεις include και το πρότυπό του (stdlib): http://c-faq.com/mal...locnocast.html. Κανονικά όμως από ANSI και μετά δεν το χρειάζεσαι. Το COPY σου όμως εμένα δεν μου κάθεται και πολύ καλά, γιατί είναι ασυνεπές ως προς το data type των 2 ορισμάτων του, τα οποία λογικά περιμένει κανείς να έχουν το ίδιο data type. Αλλά το obj πρέπει να περαστεί dereferenced και το src ως δείκτης. Βασικά ειδικά για το συγκεκριμένο δεν βρίσκω κάποιον ιδιαίτερο λόγο να φτιάξεις macro αντί να χρησιμοποιείς απευθείας την memcpy()... έτσι κι αλλιώς κι αυτή void * τα έχει τα ορίσματά της, άρα είναι από τη φύση της generic. To συγκεκριμένο macro το παρα-βρίσκω επιρρεπές σε σφάλματα. Μια κάπως καλύτερη εκδοχή του θα μπορούσε να είναι κάτι σαν κι αυτό... > #define myCOPY( pObj, pSrc, /* size*/ ) memcpy( (pObj), (pSrc), /* size */ ) που τουλάχιστον είναι συνεπές ως προς το data type των 2 λογικά ομοειδών ορισμάτων του και τα ονόματά τους δίνουν κι ένα hint ότι περιμένει δείκτες και στα 2 ορίσματα, αλλά και πάλι δεν νομίζω πως έχει λόγο ύπαρξης. Ειδικά αν τα ορίσματα αναφέρονται σε πίνακες, οπότε εκεί πια μιλάμε για πολύ μεγάλο πρόβλημα αν δεν δώσουμε explicitly το size. EDIT: Βασικά generic και για δείκτες και για πίνακες χωρίς explicit size δεν γίνεται. Με explicit size γίνεται ίδιο με την memcpy(). EDIT2: Ξέχασα, και το NEW() σου έχει ένα θέμα... δεν λειτουργεί για δημιουργία δυναμικών πινάκων. Αν αλλάξεις το 'type' σε 'size' θα λειτουργεί και για πίνακες, με την προϋπόθεση πως θα το καλείς με το σωστό size Γνωρίζω πολύ καλά τι λες, άλλωστε έδωσα κάποια παραδείγματα, γενικά επειδή είπες ότι και το NEW μου έχει κάποιο θέμα, να ξέρεις ότι αυτά τα οποία έδωσα δεν είναι για οτιδήποτε project υλοποιώ, σε μερικά τα χρησιμοποιώ ανάλογα την περίπτωση για να εξοικονομώ χρόνο. Το copy μου είναι μια χαρά, σε διαβεβαιώ, για αυτό που το χρειαζόμουν ήταν μια χαρά, αυτά που λες είναι αυτονόητα, ευχαριστώ για τις συμβουλές σου από την άλλη. Επίσης και το δεύτερο που λες πάλι το γνώριζα, για το NEW αναφέρομαι. Τέλος πάντων, επειδή ο στόχος μου ήταν άλλος, που μάλλον δεν έγινε αντιληπτός, κακώς μπήκα στην κουβέντα, δυστυχώς το forum πηγαίνει από το κακό στο χειρότερο.
migf1 Δημοσ. 3 Ιουλίου 2012 Δημοσ. 3 Ιουλίου 2012 Μόνο εγώ δεν βλέπω την ευκολία και σίγουρα την ωρεάδα της ? Για όνομα της $DEITY ρε παιδιά. Γιατί να μην τρέξετε κατευθείαν memcpy ? Η λέξη "memcpy" δεν παραπέμπει σε "copy" δηλαδή ? Τι θα κερδίσετε με το παραπάνω "alias" (γιατί δεν βλέπω να κάνει κάτι άλλο) ? ... Αυτό ακριβώς είπα κι εγώ στον φίλο bokarinhio. ... Υ.Γ. Με την πρώτη ευκαιρία θα δω τι παίζει (από περιέργεια) και στην VC++ Ωραίος! Όταν δοκιμάσεις και σε VC++ let us know ... λογικά το ίδιο θα κάνει κι εκεί. ... Τέλος πάντων, επειδή ο στόχος μου ήταν άλλος, που μάλλον δεν έγινε αντιληπτός, κακώς μπήκα στην κουβέντα, δυστυχώς το forum πηγαίνει από το κακό στο χειρότερο. Χμ. αυτό από που προέκυψε τώρα; Συζήτηση κάνουμε, δεν κάνουμε διαγωνισμό. Πολύ καλά έκανες και μπήκες στη κουβέντα, σε δημόσιο φόρουμ είμαστε.
Προτεινόμενες αναρτήσεις