defacer Δημοσ. 30 Ιουνίου 2012 Δημοσ. 30 Ιουνίου 2012 @defacer βλεπεις οτι ο ημιθεος το πηρε προσωπικα αυτο που ειπα με τους κωδικες? αρα δεν ειμαι ο μοναδικος και η κριτικη που θα σου κανει ο αλλος μπορει καμια φορα να μην ειναι και τοσο αθωα.Παρολαυτα ποσταριζα παντα κωδικα. Τελοςπαντων αυτοι πανε να μου κολλησουν την ταμπελα του τρολλ.. και θα ρωτησω για τελευταια φορα... υπαρχει θεμα με την παραμονη μου εδω μεσα? χαλαει το θρεντ? ΝΑΙ / ΟΧΙ . Μην ντραπει κανεις. Δεν εγινε και τιποτα μπορει να μην μου πηγαινουν τα φορα... τα κοβω και τελειωσε και χεστηκα και για το προγραμματισμο λες και θα βρεις να δουλεψεις πουθενα Το τι έκανε άλλος είναι δική του μαγκιά ή πρόβλημα. Εσύ εστίασε στον εαυτό σου. Αν κάποιος πάει να σου κολλήσει ταμπέλα που δεν ισχύει, τις περισσότερες φορές δεν αξίζει ν' ασχοληθείς μαζί του και το μόνο που θα καταφέρει θα είναι να γελοιοποιηθεί ο ίδιος. Υπάρχουν περιπτώσεις όπου δε μπορείς να κάτσεις να κοιτάς όταν σου πετάνε λάσπη και σκατά, αλλά αυτό προϋποθέτει ότι είσαι φτασμένος (αλλιώς δε θα κάτσει να ασχοληθεί κανείς με τα σκατά για να τα πετάξει σε σένα συγκεκριμένα) οπότε δεν είναι της παρούσης. Όσο για το αν θα βρεις δουλειά στο χώρο αυτό εξαρτάται απο σένα και μόνο. Η προσωπική μου εμπειρία δεν είναι αυτή που περιγράφεις. ΥΓ: Δε σε λέω τρολλ ούτε παίρνω θέση, ελπίζω να είναι εμφανές.
Star_Light Δημοσ. 30 Ιουνίου 2012 Δημοσ. 30 Ιουνίου 2012 @defacer Για δουλεια πλαάκα έκανα. Δεν ξερω ακομη δεν εχω ψαχθει σοβαρα αλλα απο οσο ακουω ειναι δυσκολα τα πραγματα και πρεπει να ξερεις πολλα πραγματα για να μπορεσεις να αντεξεις τον ανταγωνισμο. Εκτος και αν δουλευεις σαν ελευθερος επαγγελματιας και παιρνεις δουλειτσες.
migf1 Δημοσ. 1 Ιουλίου 2012 Δημοσ. 1 Ιουλίου 2012 Δεν είμαι και τόσο sold για τη χρησιμότητα του παραπάνω ή του κατά πόσον είναι καλή ιδέα για δύο λόγους: έχει νόμα μόνο όταν μιλάμε για primitives οπότε θα μπορούσες απλά να τα κάνεις type π.χ. σαν int ή float και να είσαι καλυμμένος στις περισσότερες των περιπτώσεων σε αντίθεση με μια function myMIN, η macro κάνει evaluate τα arguments παραπάνω από μία φορά και έχουμε "ενδιαφέρουσες" παρενέργειες αν δώσεις π.χ. myMIN(++i, ++j) Ειδικά το δεύτερο είναι πρόβλημα το οποίο για να δεχτώ την πιθανότητα να μου συμβεί όταν δεν προσέχω θα πρέπει το αναμενόμενο ώφελος να είναι πολύ μεγαλύτερο από το να γλυτώσω μια γραμμή κώδικα στις πιθανότατα ελάχιστες περιπτώσεις που δε θα έχω άλλη επιλογή από το να γράψω untyped check. Προφανώς υπάρχουν tricky parts στα macros, όπως όμως υπάρχουν και σε πληθώρα άλλων χαρακτηριστικών της γλώσσας (τα οποία σε άπειρα χέρια μπορούν να δημιουργήσουν πρόβλημα). Consider όμως κάτι σαν το παρακάτω... > // private #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TOS_WIN__) #define CON_COLOR_WIN32 #elif defined(__linux__) || defined(__unix__) || defined(__unix) \ || defined(__CYGWIN__) || defined(__GNU__) || defined(__MINGW32__) \ || defined(__MINGW64__) #define CON_COLOR_ANSI #endif typedef struct SkinItemColors { #if defined( CON_COLOR_WIN32 ) /* Windows COLORS are unisgned int === */ WORD fg; WORD bg; #elif defined( CON_COLOR_ANSI ) /* ANSI COLORS are c-strings ========= */ char fg[ CONOUT_CLRSZ ]; char bg[ CONOUT_CLRSZ ]; #endif } SkinItemColors; #if defined( CON_COLOR_WIN32 ) #define CONOUT_CPYCLR( dst, src ) \ (dst) = (src) #elif defined( CON_COLOR_ANSI ) #define CONOUT_CPYCLR( dst, src ) \ strncpy( (dst), (src), CONOUT_CLRSZ-1 ) #endif είναι τμηματικά τα #ifdefs γιατί τα έχω κάνει copy από διαφορετικά αρχεία του HexView. Πας λοιπόν public και χρησιμοποιείς κοινό interface χωρίς να σε ενδιαφέρει το private implementation του, ούτε καν στα data types του. Πχ... > // public ... SkinItemColors sic1, sic2; // assign fg & bg color of sic1 here (δεν έχω συμπεριλάβει το implementation της CONOUT_SETCOLOR() ... υπάρχει κανονικά όμως στον κώδικα του HexView CONOUT_SETCOLOR(sic1.fg, FG_BLUE); CONOUT_SETCOLOR(sic1.bg, BG_WHITE); // copy to sic2 CONOUT_CPYCLR(sic2.fg, sic2.fg); CONOUT_CPYCLR(sic2.bg, sic2.bg); ... Είναι κοινή πρακτική και πολύ συχνά ιδιαίτερα χρήσιμη. Δεν βλέπω με ποιό τρόπο η χρήση defines είναι ευκολότερη ή/και γρηγορότερη από τη χρήση global consts. Ένα πρόχειρο που μου έρχεται στο μυαλό είναι πως με #defines δεν χρειάζεται να ασχοληθείς με synchronization των globals. . Αυτή η περίπτωση στο μυαλό μου μπαίνει στην κατηγορία που έγραψα (παραμετροποίηση κώδικα πριν τον δει ο compiler), νομίζω θα συμφωνήσεις ότι για κάτι τέτοιο μιλάμε. Ακόμα κι αν διαφωνήσεις, υπάρχει λύση και χωρίς τη χρήση macro: >enum { ARRAY_SIZE = 100 }; char buf[ARRAY_SIZE]; // δεν είναι VLA Απο κει και πέρα μπορεί κάλλιστα να υπάρχουν χρήσεις που δεν έχω σκεφτεί γιατί ούτε έκατσα να το ψειρίσω 2 ώρες ούτε είμαι ο guru της C, νομίζω όμως ότι και να υπάρχουν θα μιλάμε για αρκετά edge cases. Ο μόνος λόγος που μπορώ να σκεφτώ αυτή τη στιγμή που θα προτιμούσα enum αντί για #define είναι αν ήθελα να κάνω type-checking στο compile time για τις τιμές μιας μεταβλητής, ορισμένης of enumerator type. Στο συγκεκριμένο παράδειγμα που δίνεις δεν το κάνεις και δεν χρειάζεται καν, οπότε δεν βλέπω να μειονεκτεί σε κάτι το #define έναντι του enum σε αυτό το παράδειγμα. Δεν είναι αντίφαση με την έννοια της λογικής. Λες όμως ότι χρησιμοποιούμε ποτήρι για να πιούμε νερό και επίσης χρησιμοποιούμε το λάστιχο της βρύσης για να πιούμε νερό. Είναι εύλογο να περιμένει κανείς μια διευκρίνιση, ειδικά όταν απευθύνεσαι σε κόσμο που δεν έχει εμπειρία. Στην προκειμένη κατά την άποψή μου θα ήταν πολύ σωστότερο να πεις "Για να πιούμε νερό χρησιμοποιούμε ποτήρι. Νερό μπορεί να πιεί κανείς και με το λάστιχο, έχε το υπόψη γιατί θα δεις κόσμο που το κάνει, αλλά αυτή η χρήση του λάστιχου δεν έχει κανένα απολύτως πλεονέκτημα απέναντι στο ποτήρι και πρέπει να το αποφεύγεις γιατί έχει μειονεκτήματα τα οποία πρέπει να είσαι έμπειρος για να εντοπίσεις". Σε γενικές γραμμές (δεν λέω πάντα) δεν είμαι υπερ των "γενικών συνταγών"... δεν είμαι δηλαδή οπαδός της πασπαρτού λογικής (ούτε είμαι όμως πολέμιός της). Εννοώ πως αν για κάποιον συγκεκριμένο σκοπό με εξυπηρετεί καλύτερα να πιω με το λάστιχο θα πιω με το λάστιχο, ενώ κάλλιστα μπορεί 2 γραμμές πιο κάτω να με εξυπηρετεί καλύτερα να πιω με το ποτήρι, οπότε θα πιω με το ποτήρι. Αν κάτι γίνεται με παραπάνω από 1 τρόπο χωρίς παρενέργειες, θα χρησιμοποιήσω όποιον να είναι, ανάλογα πως θα μου κάτσει εκείνη τη στιγμή (συνήθως ομως προσπαθώ να είμαι συνεπής στη χρήση του ίδιου πράγματος... επαναλαμβάνω αν δεν υπάρχει καμιά διαφορά). Για τα υπόλοιπα θα σου στείλω ένα ΠΜ κάποια στιγμή να τα πούμε με την ησυχία μας. Ok.
defacer Δημοσ. 1 Ιουλίου 2012 Δημοσ. 1 Ιουλίου 2012 Πολύ φοβάμαι πως θα... διαφωνήσω. #if defined( CON_COLOR_WIN32 ) #define CONOUT_CPYCLR( dst, src ) \ (dst) = (src) #elif defined( CON_COLOR_ANSI ) #define CONOUT_CPYCLR( dst, src ) \ strncpy( (dst), (src), CONOUT_CLRSZ-1 ) #endif [/code] Βεβαίως οι συγκεκριμένες macros δεν πρόκειται να έχουν προβλήματα στην πράξη γιατί είναι πολύ συγκεκριμένος ο μοναδικός τρόπος με τον οποίο τις χρησιμοποιείς. Παρόλα αυτά στα δικά μου μάτια είναι macros που δεν χρειάζονται γιατί μπορείς πολύ απλά να κάνεις το εξής (το οποίο παρεμπιπτόντως το κάνεις ήδη στον ορισμό του struct, οπότε δεν ξέρω γιατί επιλέγεις να σταματήσεις εκεί): >#if defined( CON_COLOR_WIN32 ) void conout_cpyclr(WORD dst, WORD src) { dst = stc; } #elif defined( CON_COLOR_ANSI ) void conout_cpyclr(char dst[], char src[]) { strncpy( (dst), (src), CONOUT_CLRSZ-1 ); } #endif Και ακόμα καλύτερα να μαζευτούν όλα τα #if defined( CON_COLOR_WIN32 ) μαζί και να γίνουν >#if defined( CON_COLOR_WIN32 ) #include <con_color_win32.h> } #elif defined( CON_COLOR_ANSI ) #include <con_color_ansi.h> #endif ...για να μπορείς μέσα στα επιμέρους includes να γράψεις σαν άνθρωπος χωρίς όλα τα #ifdef μέσα στη μάπα σου. Κι αυτό γιατί θεωρώ πως είναι πολύ πιο απίθανο να σε ενδιαφέρει να δεις τι διαφορές έχουν από πλατφόρμα σε πλατφόρμα παρά να θέλεις απλά να διαβάσεις την υλοποίηση για τη μία πλατφόρμα που σε ενδιαφέρει εκείνη τη στιγμή. Και μπορείς να κάνεις το ίδιο που κάνεις και συ παρακάτω. Ένα πρόχειρο που μου έρχεται στο μυαλό είναι πως με #defines δεν χρειάζεται να ασχοληθείς με synchronization των globals. Ούτε αυτό νομίζω πως έχει νόημα. Γενικά μιλώντας, οι globals θα έχουν αρχικοποιηθεί όλες με κάποια άγνωστη για σένα σειρά πριν ξεκινήσει η main(). Αν έχεις κώδικα που κάνει σημαντικά πράγματα στην αρχικοποίησή του πριν ξεκινήσει η main απλά θεωρώ ότι κάνεις ένα αβίαστο λάθος, καθώς θα μπορούσες να μεταφέρεις την όποια αρχικοποίηση μέσα στη main και ποτέ να μην έχεις τέτοια προβλήματα. Ειδικά μιλώντας, πάλι δε μπορώ να φανταστώ τι εννοείς. Τι διαφορά κάνει η χρήση #define αντί για κάποιου άλλου constant expression όπως αυτό με τη χρήση ενός enum στο synchronization των globals? Παράδειγμα? Ο μόνος λόγος που μπορώ να σκεφτώ αυτή τη στιγμή που θα προτιμούσα enum αντί για #define είναι αν ήθελα να κάνω type-checking στο compile time για τις τιμές μιας μεταβλητής, ορισμένης of enumerator type. Στο συγκεκριμένο παράδειγμα που δίνεις δεν το κάνεις και δεν χρειάζεται καν, οπότε δεν βλέπω να μειονεκτεί σε κάτι το #define έναντι του enum σε αυτό το παράδειγμα. Κοίτα, αν διαφωνείς με το ότι το #define έχει πολύ μεγαλύτερη δύναμη (και εξ αυτού δυνατότητα δημιουργίας προβλημάτων) απ' ότι χρειάζεται και επομένως εξορισμού πρέπει να αποφευχθεί αφού η δουλειά γίνεται εξίσου καλά με το λιγότερο δυνατό enum, δεν έχουμε κάτι παραπάνω να συζητήσουμε. Εγώ αυτό το θεωρώ αξίωμα του προγραμματισμού: χρησιμοποιείς πάντα το λιγότερο μπρουτάλ εργαλείο που σου καλύπτει όμως όλες τις απαιτήσεις. Στο συγκεκριμένο δεν βλέπω καμία απαίτηση που να καλύπτει ένα macro constant και να μη την καλύπτει η enum, οπότε enum χωρίς συζήτηση.
migf1 Δημοσ. 1 Ιουλίου 2012 Δημοσ. 1 Ιουλίου 2012 Εν τάχει επειδή με περιμένει η γυναίκα να πάμε για μπάνιο (κι έχουμε ήδη αργήσει), τα const στην C δεν είναι το ίδιο με τα const στη C++. Ένα πρόχειρο link που βρήκα: http://stackoverflow...-vs-define-in-c (διάβασα στα γρήγορα μονάχα τις 3-4 πρώτες απαντήσεις). Για την ερώτηση γιατί δεν συνεχίζω τη λογική του struct και στους ορισμούς συναρτήσεων, το έκανα περισσότερο για την ευκολία του να μην έχω να διαχειρίζομαι και function prototypes σε ένα multi-file project όπου έκανα συνεχώς αλλαγές (γιατί αν δεις τον κώδικα, είναι κι άλλα macros)... γενικώς με εξυπηρετεί περισσότερο το non-strictness των macros. Για το sync, έχω την εντύπωση πως τα const γίνονται evaluate στο run-time, αλλά τώρα που το ξανασκέφτομαι ίσως και να μην ισχύει (θα πρέπει να το ψάξω για να το βεβαιώσω/διαψέυσω). ΥΓ. Την κάνω, τα υπόλοιπα όταν γυρίσω.
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Ξανακοιτώντας σήμερα με ησυχία το θέμα, το link που έδωσα στο προηγούμενο ποστ είναι τελικά κατατοπιστικότατο και σφαιρικό. Τα #defines στην C δεν είναι απομεινάρια της 10ετίας του '80 όπως έγραψες φίλε defacer, είναι απολύτως θεμιτός και ενίοτε (ακόμα και συχνά) αναγκαίος τρόπος να διαχειρίζεσαι σταθερές και constant expressions στη C, έχοντας συγκεκριμένα πλεονεκτήματα/μειονεκτήματα έναντι των consts (όπως αναλύονται εύστοχα στο παραπάνω link). Σε ότι αφορά το thread-safeness των const, το λάθος ήταν δικό μου... είναι απολύτως thread-safe. Οπότε κρατάμε τα υπόλοιπα πλεονεκτήματα & μειονεκτήματά τους έναντι των #define. Το ζουμί που θα ήθελα εγώ να βγει από τη συγκεκριμένη συζήτηση για όσους την παρακολουθούν, είναι πως στον προγραμματισμό δεν υπάρχουν πανάκειες. Όσα περισσότερα γνωρίζει/μαθαίνει κανείς για τα εργαλεία που έχει στην διάθεσή του, τόσο καλύτερα μπορεί να επιλέξει το ποιο θα χρησιμοποιήσει την εκάστοτε δεδομένη στιγμή για το εκάστοτε δεδομένο πρόβλημα. Και ο κανόνας είναι πως όταν για ένα πρόβλημα υπάρχουν παραπάνω από 1 προσεγγίσεις, υλοποιήσεις, εργαλεία τότε η προτίμηση του ενός έναντι κάποιου άλλου θα πρέπει να γίνεται συνειδητά, βάσει των trade-offs. ΥΓ. Για την ομαδοποίηση των #ifdef που πρότεινες στον κώδικα που παρέθεσα, έχω ήδη σημειώσει πως δεν είναι αντιπροσωπευτικός γιατί προέρχεται από copy & paste διάφορων αρχείων του HexView (του οποίου ο κώδικας παρεμπιπτόντως είναι ελεύθερος).
defacer Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Ξανακοιτώντας σήμερα με ησυχία το θέμα, το link που έδωσα στο προηγούμενο ποστ είναι τελικά κατατοπιστικότατο και σφαιρικό. Τα #defines στην C δεν είναι απομεινάρια της 10ετίας του '80 όπως έγραψες φίλε defacer, είναι απολύτως θεμιτός και ενίοτε (ακόμα και συχνά) αναγκαίος τρόπος να διαχειρίζεσαι σταθερές και constant expressions στη C, έχοντας συγκεκριμένα πλεονεκτήματα/μειονεκτήματα έναντι των consts (όπως αναλύονται εύστοχα στο παραπάνω link). ΟΚ, για να δούμε... Απάντηση #1: Whenever possible, instead of macros / ellipsis, use a type-safe alternative.If you really NEED to go with a macro... Γι' αυτά που συζητάμε είναι possible ένα type-safe alternative (enum) και δε χρειάζεται macro. 1-0. Απάντηση #2: So, in most contexts, prefer the 'enum' over the alternatives. 2-0. Απάντηση #3: In C, specifically? In C the correct answer is: use #define (or, if appropriate, enum) Εδώ νομίζω ότι λέγοντας "appropriate" στην πραγματικότητα εννοεί "possible". Επιπλέον, επειδή μου φάνηκε ότι το περι enum μπήκε εκ των υστέρων στην πρόταση, είδα το edit history της απάντησης και όντως επιβεβαίωσα ότι η παρένθεση μπήκε εκ των υστέρων (στο rev. 4). Το οποίο εμένα μου λέει ότι ο συγκεκριμένος δεν είχε υπόψη το ότι μπορεί να χρησιμοποιήσει enum (και γι' αυτό ξεκινάει λέγοντας use #define), όμως το πρόσθεσε αργότερα όταν είδε και τις άλλες απαντήσεις. Για τους παραπάνω λόγους θα κάνω call 3-0. Οι παρακάτω απαντήσεις κατα πλειοψηφία δεν αναφέρουν κάν την ύπαρξη του enum (εκτός από μία που αναφέρεται μόνο σε αυτό) και συγκρίνουν το macro με ένα απλό const (το οποίο όπως έχουμε πει δεν καλύπτει όλα τα σενάρια χρήσης). Αν πιστεύεις ότι τα παραπάνω αδικούν τη θέση σου γιατί δεν αντιπροσωπεύουν το πνεύμα των απαντήσεων στο SO είμαι όλος αυτιά. Διαφορετικά είναι απορίας άξιο πώς γίνεται να βγάζεις το συμπέρασμα ότι λένε "καλό πράγμα το macro χρησιμοποίησέ το". Από την πλευρά μου έχω να πω ότι θολώνεις (ενδεχομένως όχι εσκεμμένα) τα νερά όταν λές ότι τα macro έχουν πλεονεκτήματα έναντι των consts. Δεν στηρίζω την χρήση των consts ακριβώς γιατί έχουν αυτά τα μειονεκτήματα. Στηρίζω τη χρήση των enum. Σε ότι αφορά το thread-safeness των const, το λάθος ήταν δικό μου... είναι απολύτως thread-safe. Οπότε κρατάμε τα υπόλοιπα πλεονεκτήματα & μειονεκτήματά τους έναντι των #define. As above. Το ζουμί που θα ήθελα εγώ να βγει από τη συγκεκριμένη συζήτηση για όσους την παρακολουθούν, είναι πως στον προγραμματισμό δεν υπάρχουν πανάκειες. Όσα περισσότερα γνωρίζει/μαθαίνει κανείς για τα εργαλεία που έχει στην διάθεσή του, τόσο καλύτερα μπορεί να επιλέξει το ποιο θα χρησιμοποιήσει την εκάστοτε δεδομένη στιγμή για το εκάστοτε δεδομένο πρόβλημα. Και ο κανόνας είναι πως όταν για ένα πρόβλημα υπάρχουν παραπάνω από 1 προσεγγίσεις, υλοποιήσεις, εργαλεία τότε η προτίμηση του ενός έναντι κάποιου άλλου θα πρέπει να γίνεται συνειδητά, βάσει των trade-offs. Εδώ με βρίσκεις σύμφωνο, αλλά στην απόφαση macro vs enum δε βλέπω να το εφαρμόζεις...
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 ΟΚ, για να δούμε... Απάντηση #1: Γι' αυτά που συζητάμε είναι possible ένα type-safe alternative (enum) και δε χρειάζεται macro. 1-0. Για ποιο από όλα από όσα συζητάμε εννοείς; Π.χ. για το size ενός πίνακα το type-safeness το κάνει έτσι κι αλλιώς ο compiler, άρα γιατί enum και όχι #define; (το const ελπίζω να αποδέχτηκες πως δεν κάνε για αυτήν την περίπτωση). Αν εννοείς τον ορισμό macros αντί για functions, σημείωσα ήδη πως είναι συνειδητή επιλογή μου γιατί μου δίνει την ευχέρεια να μην ασχοληθώ με διαχείριση των αντίστοιχων function prototypes (που με τη σειρά του προϋποθέτει ακόμα περισσότερα #if directives). Για ποιο άλλο συζητήσαμε που να χρειάζεται type-safeness; Απάντηση #2: 2-0. Έχει και σχολιασμό η απάντηση 2. Στη δική μας περίπτωση εδώ πέρα δεν ισχύει, αλλά γενικότερα ισχύει (π.χ, προσπάθησε να ορίσεις οτιδήποτε εκτός από int με enum.). Σημείωση: το enum σου παρέχει μονάχα int type-safety, κάτι που ούτε το χρειαζόμαστε στην περίπτωσή μας, αλλά και γενικώς η χρησιμότητά του είναι εξαιρετικά περιορισμένη συγκριτικά τόσο με το #define όσο και με το const. ) Απάντηση #3: Εδώ νομίζω ότι λέγοντας "appropriate" στην πραγματικότητα εννοεί "possible". Επιπλέον, επειδή μου φάνηκε ότι το περι enum μπήκε εκ των υστέρων στην πρόταση, είδα το edit history της απάντησης και όντως επιβεβαίωσα ότι η παρένθεση μπήκε εκ των υστέρων (στο rev. 4). Το οποίο εμένα μου λέει ότι ο συγκεκριμένος δεν είχε υπόψη το ότι μπορεί να χρησιμοποιήσει enum (και γι' αυτό ξεκινάει λέγοντας use #define), όμως το πρόσθεσε αργότερα όταν είδε και τις άλλες απαντήσεις. Για τους παραπάνω λόγους θα κάνω call 3-0. Οι παρακάτω απαντήσεις κατα πλειοψηφία δεν αναφέρουν κάν την ύπαρξη του enum (εκτός από μία που αναφέρεται μόνο σε αυτό) και συγκρίνουν το macro με ένα απλό const (το οποίο όπως έχουμε πει δεν καλύπτει όλα τα σενάρια χρήσης). Αν πιστεύεις ότι τα παραπάνω αδικούν τη θέση σου γιατί δεν αντιπροσωπεύουν το πνεύμα των απαντήσεων στο SO είμαι όλος αυτιά. Διαφορετικά είναι απορίας άξιο πώς γίνεται να βγάζεις το συμπέρασμα ότι λένε "καλό πράγμα το macro χρησιμοποίησέ το". Από την πλευρά μου έχω να πω ότι θολώνεις (ενδεχομένως όχι εσκεμμένα) τα νερά όταν λές ότι τα macro έχουν πλεονεκτήματα έναντι των consts. Δεν στηρίζω την χρήση των consts ακριβώς γιατί έχουν αυτά τα μειονεκτήματα. Στηρίζω τη χρήση των enum. See above (επίσης προσπάθησε να ορίσεις π.χ. ένα string-literal με enum ). Εδώ με βρίσκεις σύμφωνο, αλλά στην απόφαση macro vs enum δε βλέπω να το εφαρμόζεις... Δεν την εφαρμόζω γιατί δεν μου προσφέρει απολύτως τίποτα για τη δουλειά που θέλω να κάνω στο συγκεκριμένο σημείο του κώδικα. Αν ήθελα int type-safety, θα την χρησιμοποιούσα... εδώ γιατί; EDIT1: Btw, το 3ο bullet στην 2η απάντηση του SO στον gcc έχει επιλυθεί εδώ και πολύ καιρό, με το flag -g3 EDIT2: Μου ξέφυγε το παρακάτω στη γενικότερη απάντηση που έδωσα μαζί με τα πριν και τα μετά του, αλλά νομίζω χρειάζεται ξεχωριστό σχολιασμό... .. Αν πιστεύεις ότι τα παραπάνω αδικούν τη θέση σου γιατί δεν αντιπροσωπεύουν το πνεύμα των απαντήσεων στο SO είμαι όλος αυτιά. Διαφορετικά είναι απορίας άξιο πώς γίνεται να βγάζεις το συμπέρασμα ότι λένε "καλό πράγμα το macro χρησιμοποίησέ το". Από την πλευρά μου έχω να πω ότι θολώνεις (ενδεχομένως όχι εσκεμμένα) τα νερά όταν λές ότι τα macro έχουν πλεονεκτήματα έναντι των consts. Δεν στηρίζω την χρήση των consts ακριβώς γιατί έχουν αυτά τα μειονεκτήματα. Στηρίζω τη χρήση των enum. ... Γιατί θολώνω τα νερά; Δεν έχουν ξεκάθαρα πλεονεκτήμα (και ξεκάθαρα μειονεκτήματα) έναντι των consts; Δεν καταλαβαίνω τι θέλεις να πεις εδώ πέρα. Επίσης, δεν υποστήριξα πουθενά πως στο link που έδωσα η ερμηνεία μου είναι "καλό πράγμα το macro χρησμοποιήσέ το". Υποστήριξα πως το εν λόγω link καλύπτει συγκεντρωμένα τα υπέρ και τα κατά των διαθέσιμων εργαλείων (#define, const & enum). Αν θες όμως την ερμηνεία μου για το "So, in most contexts, prefer the 'enum' over the alternatives" είναι η εξής: "αν δεν ξέρεις τι ακριβώς κάνεις και γιατί, τότε χρησιμοποίησε το τάδε εργαλείο (enum εδώ πέρα) για να έχεις το κεφάλι σου ήσυχο". Αν ξέρεις όμως τι κάνεις και γιατί, είσαι ελεύθερος και είναι απόλυτα θεμιτό έως και προτεινόμενο να χρησιμοποιήσεις όποιο εργαλείο θεωρείς πιο κατάλληλο για τον εκάστοτε σκοπό σου.
defacer Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Για ποιο από όλα από όσα συζητάμε εννοείς; Π.χ. για το size ενός πίνακα το type-safeness το κάνει έτσι κι αλλιώς ο compiler, άρα γιατί enum και όχι #define; (το const ελπίζω να αποδέχτηκες πως δεν κάνε για αυτήν την περίπτωση). Αν εννοείς τον ορισμό macros αντί για functions, σημείωσα ήδη πως είναι συνειδητή επιλογή μου γιατί μου δίνει την ευχέρεια να μην ασχοληθώ με διαχείριση των αντίστοιχων function prototypes (που με τη σειρά του προϋποθέτει ακόμα περισσότερα #if directives). Για ποιο άλλο συζητήσαμε που να χρειάζεται type-safeness; To type safety στην προκειμένη δε χρειάζεται strictly, παρόλο που παρέχεται "δωρεάν". Αυτό στο οποίο θα έπρεπε να εστιάσεις είναι το "if you NEED". Προφανώς "you do not NEED" γιατί γίνεται εξίσου καλά (βασικά καλύτερα) και αλλιώς. Όσο για το const ποτέ δεν υποστήριξα ότι κάνει γι' αυτή την περίπτωση -- μπορείς να ανατρέξεις στα προηγούμενα post και να με διαψεύσεις αν θέλεις, διαφορετικά το παίρνω σαν μια άτυχη έκφραση εκ μέρους σου. Έχει και σχολιασμό η απάντηση 2. Στη δική μας περίπτωση εδώ πέρα δεν ισχύει, αλλά γενικότερα ισχύει (π.χ, προσπάθησε να ορίσεις οτιδήποτε εκτός από int με enum.). Σημείωση: το enum σου παρέχει μονάχα int type-safety, κάτι που ούτε το χρειαζόμαστε στην περίπτωσή μας, αλλά και γενικώς η χρησιμότητά του είναι εξαιρετικά περιορισμένη συγκριτικά τόσο με το #define όσο και με το const. Για τις ανάγκες αυτής της συζήτησης δεν με ενδιαφέρει να ορίσω οτιδήποτε εκτός από int, και επίσης δεν κάνει apply ο σχολιασμός της απάντησης #2 (άρα γιατί τον αναφέρεις?). Αν χρειαστεί, θα χρησιμοποιήσω const. Αν αυτό δε γίνεται, θα χρησιμοποιήσω macro. Να πω για νιοστή φορά ότι η αντίρρησή μου δεν είναι πως προτείνεις macro αλλά πως προτείνεις macro πάνω από άλλες εναλλακτικές που δουλεύουν στις περιπτώσεις που εξετάζουμε; Δεν την εφαρμόζω γιατί δεν μου προσφέρει απολύτως τίποτα για τη δουλειά που θέλω να κάνω στο συγκεκριμένο σημείο του κώδικα. Αν ήθελα int type-safety, θα την χρησιμοποιούσα... εδώ γιατί; Το έχω πει πολλές φορές, αλλά απ' ότι φαίνεται πρέπει να δώσω παράδειγμα: γιατί με macro γίνεται αυτό ενώ με enum δε γίνεται. Μπορεί να πεις "μπα προσέχω οπότε δε γίνεται" αλλά δε με ενδιαφέρει αν προσέχεις εσύ προσωπικά. Με ενδιαφέρει ότι στη μία περίπτωση υπάρχει πιθανότητα != 0 να εμφανιστεί πρόβλημα ενώ στην άλλη η πιθανότητα είναι ακριβώς μηδέν. Απλά μαθηματικά. Γιατί θολώνω τα νερά; Δεν έχουν ξεκάθαρα πλεονεκτήμα (και ξεκάθαρα μειονεκτήματα) έναντι των consts; Δεν καταλαβαίνω τι θέλεις να πεις εδώ πέρα. Θέλω να πω ότι ποτέ δεν μίλησα για consts παρά μόνο αφότου εσύ τα έβαλες στην κουβέντα (τα προηγούμενά μας post υπάρχουν, μπορείς να ανατρέξεις). Επίσης, δεν υποστήριξα πουθενά πως στο link που έδωσα η ερμηνεία μου είναι "καλό πράγμα το macro χρησμοποιήσέ το". Υποστήριξα πως το εν λόγω link καλύπτει συγκεντρωμένα τα υπέρ και τα κατά των διαθέσιμων εργαλείων (#define, const & enum). Σ' αυτό έχεις δίκιο. Ας βγάλει ο καθένας τα δικά του συμπεράσματα λοιπόν σχετικά με το τι προκύπτει από το link. Αν θες όμως την ερμηνεία μου για το "So, in most contexts, prefer the 'enum' over the alternatives" είναι η εξής: "αν δεν ξέρεις τι ακριβώς κάνεις και γιατί, τότε χρησιμοποίησε το τάδε εργαλείο (enum εδώ πέρα) για να έχεις το κεφάλι σου ήσυχο". Αν ξέρεις όμως τι κάνεις και γιατί, είσαι ελεύθερος και είναι απόλυτα θεμιτό έως και προτεινόμενο να χρησιμοποιήσεις όποιο εργαλείο θεωρείς πιο κατάλληλο για τον εκάστοτε σκοπό σου. Αδικείς τόσο πολύ τον poster της απάντησης που εξοργίζομαι εγώ εκ μέρους του. Ο άνθρωπος έχει ήδη αναλύσει σε βάθος και μετά βγάζει το συμπέρασμα σε μία γραμμή: "τις περισσότερες φορές που μπορείς να κάνεις τη δουλειά σου με παραπάνω από 1 τρόπους, προτίμησε την enum". Αυτό τώρα εσύ το διαστρεβλώνεις σε "αν δεν ξέρεις τι κάνεις" για να συνεχίσεις μετά ότι εσύ που ξέρεις τι κάνεις είσαι και δικαιολογημένος να χρησιμοποιήσεις macro ενώ μπορείς και να μην το κάνεις (γιατί αν δεν έχεις άλλη επιλογή δεν υπάρχει και θέμα συζήτησης). Αν θες την ερμηνεία μου για το παραπάνω, είναι η εξής: "έχω μάθει με macro και δε βλέπω για ποιό λόγο πρέπει να σκοτιστώ να αλλάξω τη συνήθειά μου". Σου έδωσα παραπάνω ένα λόγο και παραδέχομαι ότι είναι μάλλον ακαδημαϊκός παρά πρακτικός, οπότε για σένα προσωπικά μπορεί να μην έχει αξία. Εδώ όμως ο σκοπός μου δεν είναι να αλλάξω τη δική σου προσωπική συνήθεια (ποσώς με αφορά εφόσον δεν είμαστε συνεργάτες) αλλά να δείξω το σωστό δρόμο σε κάποιον που είναι φρέσκος και ακόμα δεν έχει αποκτήσει καμία συνήθεια. I rest my case.
capoelo Δημοσ. 2 Ιουλίου 2012 Μέλος Δημοσ. 2 Ιουλίου 2012 Ρε παιδιά,ποιο είναι το λάθος μου εδώ; >#include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) { char str[]="tom"; strcpy(str,"dimitris"); printf(str); system("Pause"); return 0; } Αφού τη δηλώνω ως unsized!!!
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 ... Αδικείς τόσο πολύ τον poster της απάντησης που εξοργίζομαι εγώ εκ μέρους του. Ο άνθρωπος έχει ήδη αναλύσει σε βάθος και μετά βγάζει το συμπέρασμα σε μία γραμμή: "τις περισσότερες φορές που μπορείς να κάνεις τη δουλειά σου με παραπάνω από 1 τρόπους, προτίμησε την enum". Αυτό τώρα εσύ το διαστρεβλώνεις σε "αν δεν ξέρεις τι κάνεις" για να συνεχίσεις μετά ότι εσύ που ξέρεις τι κάνεις είσαι και δικαιολογημένος να χρησιμοποιήσεις macro ενώ μπορείς και να μην το κάνεις (γιατί αν δεν έχεις άλλη επιλογή δεν υπάρχει και θέμα συζήτησης). Αν θες την ερμηνεία μου για το παραπάνω, είναι η εξής: "έχω μάθει με macro και δε βλέπω για ποιό λόγο πρέπει να σκοτιστώ να αλλάξω τη συνήθειά μου". Σου έδωσα παραπάνω ένα λόγο και παραδέχομαι ότι είναι μάλλον ακαδημαϊκός παρά πρακτικός, οπότε για σένα προσωπικά μπορεί να μην έχει αξία. Εδώ όμως ο σκοπός μου δεν είναι να αλλάξω τη δική σου προσωπική συνήθεια (ποσώς με αφορά εφόσον δεν είμαστε συνεργάτες) αλλά να δείξω το σωστό δρόμο σε κάποιον που είναι φρέσκος και ακόμα δεν έχει αποκτήσει καμία συνήθεια. I rest my case. Μπορείς να δεις τον κώδικά μου στη Ναυμαχία που είναι ΠΗΧΤΡΑ στα typedef enum {} Type; Όταν θέλω type-safeness το χρησιμοποιώ, όταν δεν το θέλω δεν το χρησιμοποιώ! ΥΓ. Το να αμφισβητείς διαρκώς τα λεγόμενά μου και να τα θεωρείς εν πολλοίς διαλεκτικά τεχνάσματα είναι δικαίωμά σου, αλλά είναι πραγματικά πολύ κουραστικό! EDIT: Έχεις δίκiο για το ότι δεν "διαφήμιζες" το const αλλά το enum. Sorry about that!
Anubis13 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Ποιο είναι το πρόβλημα? Σε μένα γίνεται compile.
migf1 Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 Ρε παιδιά,ποιο είναι το λάθος μου εδώ; >#include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) { char str[]="tom"; strcpy(str,"dimitris"); printf(str); system("Pause"); return 0; } Αφού τη δηλώνω ως unsized!!! Κοπιάρεις ένα string-literal 9 χαρακτήρων σε ένα string που το έχεις ορίσει να έχει το πολύ 4 θέσεις.
moukoublen Δημοσ. 2 Ιουλίου 2012 Δημοσ. 2 Ιουλίου 2012 > : : char str[]="tom"; : : Αφού τη δηλώνω ως unsized!!! Το οτι το δηλώνεις unsized δε σημαίνει ότι έχεις άπειρο χώρο και για πάντα.
capoelo Δημοσ. 2 Ιουλίου 2012 Μέλος Δημοσ. 2 Ιουλίου 2012 Αφού όμως είναι δηλωμένη ως unsized δεν μπορώ να της αλλάξω το μέγεθος;Υπάρχει κάποιος περιορισμός;
Προτεινόμενες αναρτήσεις