albNik Δημοσ. 12 Μαΐου 2013 Δημοσ. 12 Μαΐου 2013 Αν το κανεις αυτό στον αναδρομικό θα δεις τα Data της σειρας Height-1 απο αριστερά στα δεξιά. if(h==Height-1) printf("%d ", n->Data); Θα έχεις ενα πίνακα με τους κόμβους Height-1 και ένα μετρητή index έξω από την func. if(h==Height-1) myarr[index++]=n; Στο τέλος θα κοιτάξεις τα παιδια αυτών των κόμβων 1. να μην έχει παιδι κάποιος κόμβος αν ο προηγουμενος του δεν εχει δυο παιδιά. 2. να μην εχει δεξιό παιδι χωρις αριστερο
imitheos Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Για να μην πηδήξουμε το νήμα δηλωση δυσδιαστατου πινακα c++ με άσχετα πράγματα (που μάλιστα είναι θεωρητικά-φιλοσοφικά θέματα) παίρνω το θάρρος να κάνω quote ένα μήνυμα εδώ. @imitheos: Ακριβώς αυτό λέει το πρότυπο, το έχω κοκκινήσει κιόλας. Συνεπικουρούμενο λοιπόν και με τη δική μου εμπειρία αλλά και με την κοινή πρακτική δεκαετίες τώρα δεν βρίσκω τον λόγο να το συνεχίζουμε. Ο καθένας έχει τις απόψεις του και τις εμπειρίες του. Ώρες ώρες ρε συ migf1 σκας γάιδαρο Καταρχάς ας δούμε το 2ο κομμάτι του μηνύματος και μετά να πάμε στην παράγραφο του προτύπου. Το "συνεπικουρούμενο με τη δική μου εμπειρία" είναι επιχείρημα ? "Ο migf1 ο σουγιάς και ο τάδε ο γκοτζίλας λένε ότι το 2d->1d παίζει σωστά" Ή μια συμπεριφορά διέπεται από ένα "νόμο" (δηλαδή μια παράγραφο του προτύπου) ή δεν διέπεται. #include <stdio.h> #include <limits.h> int main(void) { int k=INT_MIN; k--; printf("k=%d - %d\n",k, k == INT_MAX); return 0; } % gcc -Wall -O2 -fstrict-overflow -o zgcc foo.c % clang -o zcl foo.c % ./zcl ; ./zgcc k=2147483647 - 1 k=2147483647 - 1 "Σύμφωνα με την εμπειρία μου" το παραπάνω παίζει έτσι παντού. Δεν παύει όμως να είναι αόριστη συμπεριφορά. undefined behavior behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements EXAMPLE An example of undefined behavior is the behavior on integer overflow. Ας πάμε τώρα στο τμήμα του προτύπου που έκανες quote τότε. EXAMPLE Consider the array object defined by the declaration int x[3][5]; Here x is a 3 × 5 array of ints; more precisely, x is an array of three element objects, each of which is an array of five ints. In the expression x, which is equivalent to (*((x)+(i))), x is first converted to a pointer to the initial array of five ints. Then i is adjusted according to the type of x, which conceptually entails multiplying i by the size of the object to which the pointer points, namely an array of five int objects. The results are added and indirection is applied to yield an array of five ints. When used in the expression x[j], that array is in turn converted to a pointer to the first of the ints, so x[j] yields an int. Το κομμάτι που έκανα bold ήταν που είχες κόκκινο. Στην έκφραση x έχουμε πρόσθεση i φορές το μέγεθος του στοιχείου του πίνακα (που το στοιχείο είναι ένας πίνακας 5 ακεραίων) και όμοια όταν βάζουμε και το [j] παίρνουμε ένα δείκτη στο τάδε στοιχείο οπότε παίρνουμε ένα int. Φυσικά θα πάρουμε int αφού ο πίνακας μας έχει ακεραίους. Σε ποιο σημείο η παραπάνω bold πρόταση ορίζει ότι μπορείς να μεταχειρίζεσαι ένα 2d πίνακα σαν να ήταν 1d ? Ασχέτως αν ο κώδικας που προκύπτει τελικά για την προσπέλαση είναι ο ίδιος, δεν παύει να μην είναι ορισμένη συμπεριφορά. Για τον ίδιο λόγο, όπως έχουμε πει πολλές φορές, η έκφραση x[1][0] είναι σωστή ενώ η έκφραση x[0][5] είναι λάθος άσχετα αν και οι δύο καταλήγουν στο ίδιο κώδικα (x+1*5+0 και x+0*5+5). Edit2: Για να μην παρεξηγηθώ, να ξαναπώ για όσους δεν παρακολούθησαν τη συζήτηση ότι θα παίξει παντού όπως λέει ο migf1. Υπάρχουν κάποια πράγματα που ενώ το πρότυπο δεν λέει τίποτα οπότε θεωρητικά δεν είναι εγγυημένα, δεν υπάρχει κανένα νόημα να υλοποιηθούν διαφορετικά. Όχι μόνο δεν υπάρχει κέρδος αλλά υπάρχει περισσότερος φόρτος για τον developer αν υλοποιηθούν διαφορετικά. Και αυτό είναι μια τέτοια περίπτωση. Edit: Ο editor τον παίρνει άγρια. Μου χάλασε όλο το μήνυμα. Ελπίζω να φαίνεται σωστά τώρα.
migf1 Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Για να μην πηδήξουμε το νήμα δηλωση δυσδιαστατου πινακα c++ με άσχετα πράγματα (που μάλιστα είναι θεωρητικά-φιλοσοφικά θέματα) παίρνω το θάρρος να κάνω quote ένα μήνυμα εδώ. Ώρες ώρες ρε συ migf1 σκας γάιδαρο Καταρχάς ας δούμε το 2ο κομμάτι του μηνύματος και μετά να πάμε στην παράγραφο του προτύπου. Το "συνεπικουρούμενο με τη δική μου εμπειρία" είναι επιχείρημα ? "Ο migf1 ο σουγιάς και ο τάδε ο γκοτζίλας λένε ότι το 2d->1d παίζει σωστά" Μερικοί ακόμα από τους κυριολεκτικά μυριάδες "τάδε γκοτζίλες" και "σουγιάδες": http://c-faq.com/aryptr/dynmuldimary.html (array3) http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html http://digital.ni.com/public.nsf/allkb/862567530005F09C862565C40072CBFF http://en.wikibooks.org/wiki/C_Programming/Common_practices#Dynamic_multidimensional_arrays Ο defacer κι εσύ μας λέτε πως στη θεωρία είναι UB το i*COLS+j, εγώ (και κάτι εκατομμύρια ακόμα σουγιάδες, γκοτζίλες, επαγγελματίες, ερασιτέχνες, πανεπιστήμια, κλπ) σας λέμε πως λειτουργεί απροβλημάτιστα παντού και πάντα επί δεκαετίες, με συγκεκριμένα πλεονεκτήματα & μειονεκτήματα. Αν τώρα θεωρείτε χρήσιμο για όσους διαβάζουν το νήμα να τους αποτρέψετε από το να χρησιμοποιούν επειδή το θεωρείτε UB, πολύ απλά δεν πρόκειται να συμφωνήσω ποτέ. Διότι πολύ απλά όπως καταλαβαίνεις το τι λέει ο σουγιάς ημίθεος και ο γκοτζίλας defacer στο φόρουμ του insomnia είναι πολύ χαμηλά στην προσωπική μου λίστα προτεραιοτήτων όταν καλούνται να "αντιπαρατεθούν" με πείρα και πρακτική δεκαετιών (και δικής μου και πάαααααααααααρα πολλών όλων) σε πληθώρα πλατφορμών και compilers. Η δική μου άποψη λοιπόν παραμένει πως δεν υπάρχει απολύτως κανένας λόγος για οποιονδήποτε διαβάζει το φόρουμ να μην ωφεληθεί στην πράξη π.χ. από την σημαντικά πιο απλή διαχείριση μνήμης, parameter passing, copying, trasnmiting, serializing, κι ένα κάρο άλλα πράγματα που υλοποιούνται πολύ πιο απλά με 1Δ πίνακες. Ομοίως και για το int *walk = (int *)arr2d Από τη στιγμή που αποδέχεσαι πως καταλήγει σε δείκτη σε int, κι από τη στιγμή που η μνήμη είναι guaranteed συνεχόμενη, πως είναι δυνατόν να μην αποδέχεσαι πως μπορείς να κάνεις αριθμητική δεικτών με τον *walk; Ειλικρινά απορώ! Εν πάσει περιπτώσει (παρόλο που δεν σου αρέσει να το ακούς ), η εμπειρία μου πάνω σε αυτά είναι τόση και τέτοια (και προφανώς δεν εννοώ μόνο δικούς μου κώδικες & δουλειές) που δεν υπάρχει περίπτωση να την αντισταθμίσει ένας άγνωστος imitheos (χωρίς παρεξήγηση) κι ένας άγνωστος defacer (με παρεξήγηση, γιατί δεν σας έχω στο ίδιο τσουβάλι) στο φόρουμ του insomnia. Στην τελική, αν βρεθεί κανείς σε πλατφόρμα ή/και compiler που του βγάζει πρόβλημα (προσωπικά δεν έχω βρει καμία) ας μην το χρησιμοποιήσει. Δεν είναι άλλωστε κανείς υποχρεωμένος. Πάντως έχω ήδη δώσει και ψαγμένο link και για αυτό (σχετικά με benchmarking) που χρησιμοποιεί ακριβώς αυτή την τεχνική, μαζί με άλλες.
imitheos Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Μερικοί ακόμα από τους κυριολεκτικά μυριάδες "τάδε γκοτζίλες" και "σουγιάδες": http://c-faq.com/aryptr/dynmuldimary.html (array3) http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html http://digital.ni.com/public.nsf/allkb/862567530005F09C862565C40072CBFF http://en.wikibooks.org/wiki/C_Programming/Common_practices#Dynamic_multidimensional_arrays Ο defacer κι εσύ μας λέτε πως στη θεωρία είναι UB το i*COLS+j, εγώ (και κάτι εκατομμύρια ακόμα σουγιάδες, γκοτζίλες, επαγγελματίες, ερασιτέχνες, πανεπιστήμια, κλπ) σας λέμε πως λειτουργεί απροβλημάτιστα παντού και πάντα επί δεκαετίες, με συγκεκριμένα πλεονεκτήματα & μειονεκτήματα. Ομοίως και για το int *walk = (int *)arr2d Καλά κοροϊδευόμαστε τώρα ? Η array3 δηλώνεται ως int *array3 = malloc(nrows * ncolumns * sizeof(int)) και προσπελαύνεται ως array3[i * ncolumns + j]. Δηλαδή δηλώνεται 1d και δουλεύεται σαν 1d. Πότε είπα αυτό είναι UB ? Μια μέθοδος είναι αν θέλεις διαστάσεις Μ χ Ν να δημιουργήσεις ένα μονοδιάστατο με διάσταση το γινόμενο M*N και μετά να εξομοιώνεις την προσπέλαση του σαν να ήταν δισδιάστατος. Ο migf1 έχει πολλά μηνύματα που περιγράφει αυτή τη τακτική και μάλιστα έγραψε ένα πριν λίγες ώρες αν θυμάμαι καλά.Δες τα 2-3 μηνύματα πριν από το μήνυμά σου που έδωσες τι κώδικα είχανε και επίσης τι λέει η ερώτηση της SO. Αυτό που είπαμε ότι είναι UB είναι να έχεις A[M][N] και μετά να θέτεις ένα δείκτη στην αρχή και να διασχίζεις την περιοχή (το quote σου "ομοίως ..." που έκανα bold). Διότι πολύ απλά όπως καταλαβαίνεις το τι λέει ο σουγιάς ημίθεος στο φόρουμ του insomnia είναι πολύ χαμηλά στην προσωπική μου λίστα προτεραιοτήτων όταν καλούνται να "αντιπαρατεθούν" με πείρα και πρακτική δεκαετιών (και δικής μου και πάαααααααααααρα πολλών όλων) σε πληθώρα πλατφορμών και compilers.Ο imitheos φυσικά είναι χαμηλά και πολλές φορές λέει μ.κίες. Αυτό όμως όταν πρόκειται για λόγια του imitheoy. Αντίθετα όταν ο Χ κάποιος κάνει quote το πρότυπο, τότε δεν μετράει ποιος είναι αυτός και η αξία είναι του προτύπου. Στην τελική, αν βρεθεί κανείς σε πλατφόρμα ή/και compiler που του βγάζει πρόβλημα (προσωπικά δεν έχω βρει καμία) ας μην το χρησιμοποιήσει. Δεν είναι άλλωστε κανείς υποχρεωμένος. Πάντως έχω ήδη δώσει και ψαγμένο link και για αυτό (σχετικά με benchmarking) που χρησιμοποιεί ακριβώς αυτή την τεχνική, μαζί με άλλες.Context matters. Το link είχε σκοπό να κάνει benchmarking και όχι να δοκιμάσει το conformance ενός compiler στο πρότυπο. Για αυτό το λόγο δοκίμασε διάφορες κοινές πρακτικές και πολύ καλά έκανε. Όταν όμως μιλάμε για UB και conformance, το link όχι μόνο δεν είναι ψαγμένο αλλά είναι και εκτός θέματος. Εν πάσει περιπτώσει (παρόλο που δεν σου αρέσει να το ακούς ),Δεν έχω κανένα πρόβλημα να ακούω το πόσα χρόνια εμπειρία έχεις απλά δεν μπορώ να το θεωρήσω επιχείρημα. η εμπειρία μου πάνω σε αυτά είναι τόση και τέτοια (και προφανώς δεν εννοώ μόνο δικούς μου κώδικες & δουλειές) που δεν υπάρχει περίπτωση να την αντισταθμίσει ένας άγνωστος imitheos (χωρίς παρεξήγηση) κι ένας άγνωστος defacer (με παρεξήγηση, γιατί δεν σας έχω στο ίδιο τσουβάλι) στο φόρουμ του insomnia.Με άλλα λόγια "ό,τι και να λέτε εγώ από το μυαλό μου δεν βγαίνω". Γιατί να χαλάμε το χρόνο μας τότε ? Νομίζω δεν έχει κανένα νόημα να συζητάμε άλλο.
migf1 Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 (επεξεργασμένο) Καλά κοροϊδευόμαστε τώρα ? Αυτό αναρωτιέμαι κι εγώ... Η array3 δηλώνεται ως int *array3 = malloc(nrows * ncolumns * sizeof(int)) και προσπελαύνεται ως array3[i * ncolumns + j]. Δηλαδή δηλώνεται 1d και δουλεύεται σαν 1d. Πότε είπα αυτό είναι UB ? Αυτό ακριβώς έγραψα κι εγώ με κώδικα, βγήκε ο defacer να μας πει πως είναι UB, κι εσύ επικρότησες. Οπότε μάλλον κοροϊδευόμαστε. Ο imitheos φυσικά είναι χαμηλά και πολλές φορές λέει μ.κίες. Αυτό όμως όταν πρόκειται για λόγια του imitheoy. Αντίθετα όταν ο Χ κάποιος κάνει quote το πρότυπο, τότε δεν μετράει ποιος είναι αυτός και η αξία είναι του προτύπου. Context matters. Το link είχε σκοπό να κάνει benchmarking και όχι να δοκιμάσει το conformance ενός compiler στο πρότυπο. Για αυτό το λόγο δοκίμασε διάφορες κοινές πρακτικές και πολύ καλά έκανε. Όταν όμως μιλάμε για UB και conformance, το link όχι μόνο δεν είναι ψαγμένο αλλά είναι και εκτός θέματος. Δεν έχω κανένα πρόβλημα να ακούω το πόσα χρόνια εμπειρία έχεις απλά δεν μπορώ να το θεωρήσω επιχείρημα. Με άλλα λόγια "ό,τι και να λέτε εγώ από το μυαλό μου δεν βγαίνω". Γιατί να χαλάμε το χρόνο μας τότε ? Νομίζω δεν έχει κανένα νόημα να συζητάμε άλλο. Σαφώς και δεν βγαίνω από το μυαλό μου κι εξήγησα επαρκώς το γιατί. Να το ξαναπω άλλη μια φορά: το έχω χρησιμοποιήσει απροβλημάτιστα επί πάμπολλα χρόνια, σε πολλές και διάφορες πλατφόρμες, σε ακόμα περισσότερους compilers και με πάμπολλους συναδέλφους. UB ή όχι, η ουσία είναι πως δουλεύει απροβλημάτιστα παντού και πάντα μέχρι τώρα, εδώ και πολλές δεκαετίες. Αν ποτέ σου τύχει να ασχοληθείς κι εσύ επί τούτου σε σοβαρά πρότζεκτς, είσαι ελεύθερος να μην το χρησιμοποιήσεις, επειδή στην θεωρία είναι UB. Εγώ και πάμπολλοι ακόμα το έχουμε χρησιμοποιήσει, το χρησιμοποιoύμε και θα συνεχίσουμε να το χρησιμοποιούμε όταν χρειαζόμαστε τα πλεονεκτήματά του, μιας και η αξιοπιστία και η αποτελεσματικότητά του είναι χιλιοδοκιμασμένη σε όποια πιθανή κι απίθανη πλατφόρμα/compiler έχει πέσει στα χέρια μας τις τελευταίες δεκαετίες. As simple as that. Επεξ/σία 14 Μαΐου 2013 από migf1
imitheos Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Αυτό ακριβώς έγραψα κι εγώ με κώδικα, βγήκε ο defacer να μας πει πως είναι UB, κι εσύ επικρότησες. Οπότε μάλλον κοροϊδευόμαστε. Με είδες να έχω κάνει quote τον κώδικά σου ? Εγώ σχολίασα ακριβώς αυτό που έχω κάνει quote. Η ερώτηση της SO που δίνει ο defacer και το μήνυμα που έδωσες εσύ δεν μιλάνε για A[N*M] αλλά για A[N][M] το οποίο είναι UB. Σαφώς και δεν βγαίνω από το μυαλό μου κι εξήγησα επαρκώς το γιατί. Να το ξαναπω άλλη μια φορά: το έχω χρησιμοποιήσει απροβλημάτιστα επί πάμπολλα χρόνια, σε πολλές και διάφορες πλατφόρμες, σε ακόμα περισσότερους compilers και με πάμπολλους συναδέλφους. UB ή όχι, η ουσία είναι πως δουλεύει απροβλημάτιστα παντού και πάντα μέχρι τώρα, εδώ και πολλές δεκαετίες. Αν ποτέ σου τύχει να ασχοληθείς κι εσύ επί τούτου σε σοβαρά πρότζεκτς, είσαι ελεύθερος να μην το χρησιμοποιήσεις, επειδή στην θεωρία είναι UB. Εγώ και πάμπολλοι ακόμα το έχουμε χρησιμοποιήσει, το χρησιμοποιoύμε και θα συνεχίσουμε να το χρησιμοποιούμε όταν χρειαζόμαστε τα πλεονεκτήματά του, μιας και η αξιοπιστία και η αποτελεσματικότητά του είναι χιλιοδοκιμασμένη σε όποια πιθανή κι απίθανη πλατφόρμα/compiler έχει πέσει στα χέρια μας τις τελευταίες δεκαετίες. Και εσύ είσαι ελεύθερος να το χρησιμοποιείς. Και εγώ όμως είμαι ελεύθερος να σχολιάζω ότι είναι λάθος κάθε φορά που το γράφεις. Το ότι χρησιμοποιείς κάτι επί πάμπολλα χρόνια και το ότι έχεις εμπειρία δεν είναι επιχειρήματα. Και register σε βλέπω να χρησιμοποιείς συχνά-πυκνά και να αφαιρείς const με cast σε έχω δει. Επειδή στη πράξη τα χρησιμοποιείς χρόνια να μην πω ότι είναι λάθος και μπορεί να οδηγήσουν σε προβλήματα ? Επί πάμπολλα χρόνια σε DOS γράφονταν προγράμματα που έθεταν ακέραιες τιμές σε δείκτες και όλα έπαιζαν τζάμι. Αφού έπαιζε τόσα χρόνια θα είναι καλή πρακτική. Και τα επιχειρήματα για το ποιος είναι ο imitheos και ο defacer είναι μπούρδες. Ο ίδιος ο DMR να αναστηθεί και να έρθει να σου το πει, δεν πρόκειται να βγεις από το μυαλό σου. Επειδή λοιπόν εγώ δεν έχω 30 χρόνια εμπειρίας και δεν έχω ασχοληθεί με σοβαρά πρότζεκτς, ας πάω να κάνω τις ποταπές δουλειές μου αντί να χάνω χρόνο εδώ.
Erevis Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Άλλο ένα θύμα του misconception ότι στη C array == pointer.
Timonkaipumpa Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Ρε παίδες.. και κυρίως όσοι έχουν καλή εμπειρία από ξένα forums... Η φαγωμάρα που παρατηρείται σε ελληνικά forums προγραμματισμού παρατηρείται και σε ξένα; Ή είναι άλλο ένα Π.Ο.Π. μαζί με την φέτα;
defacer Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 (επεξεργασμένο) Update: post deleted γιατί απλά είχαμε άδικο (όχι στην ερμηνεία του στάνταρ αλλά όσον αφορά το κράξιμο), μιας και το allocation γίνεται σαν 1d και όχι σαν 2d. Note to self: αυτά παθαίνεις όταν διαβάζεις κώδικα χωρίς να δίνεις τη δέουσα προσοχή. @timon: http://xkcd.com/386/ @imitheos: Μετά από ώριμη σκέψη καταλήγω στο συμπέρασμα ότι σε πήρα στο λαιμό μου γιατί διάβασες το post και τα links και "με πίστεψες" ότι αυτό κάνει και ο κώδικας. Ακόμα κι αν δεν έγινε ακριβώς έτσι, υποθέτω ότι έπαιξα και γω το ρόλο μου. Sorry mate. Επεξ/σία 14 Μαΐου 2013 από defacer
moukoublen Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Χωρίς καμία πρόθεση να μπω στη μέση του οποιουδήποτε "ερωτικού" κλίματος υπάρχει μεταξύ σας, σαν απλός αναγνώστης μπερδεύτηκα λιγάκι. Ο migf1 στο άλλο θέμα ο κώδικας που παραθέτει είναι σε συντομία αυτός arr = new int[n * m](); for (int i = 0; i < n * m; i++) { int row = i / m; int col = i % m; cout << "arr[" << row << "][" << col << "]: "; cout << arr[i]; // <---- Array Access cout << endl; } Sorry παίδες αλλά δε μπορώ να καταλάβω που ακριβώς μπορεί να προκύψει UB σε αυτή τη χρήση. Αφού όπως είπε και ο ίδιος ο imitheos τον δεσμεύει και τον διαχειρίζεται σα μονοδιάστατο. Άλλο θέμα αν είναι καλό ή κακό για τον κάθε φορά σκοπό. UB δε μπορώ να καταλάβω που προκύπτει, 1
defacer Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 moukoublen είσαι τηλεπαθητικός. Ξαναδιάβαζα τον κώδικα στο άλλο thread και συνειδητοποίησα ακριβώς αυτό που λες, το οποίο ισχύει 100%. Ήρθα να ποστάρω και είδα ότι με πρόλαβες. Επομένως sorry, mea culpa και ειλικρινής συγγνώμη για το abuse παραπάνω, όντως και το allocation και το access γίνεται σαν 1d οπότε δεν υπάρχει κανένα πρόβλημα. Προσωπικά μπερδεύτηκα από το output του κώδικα στο άλλο thread, διάβασα επι τροχάδην το post με τη c++ version και δεν έδωσα την πρέπουσα σημασία στο πώς γίνεται το allocation. migf1, αντί να μαλώνουμε πες μας ρε άνθρωπε αυτό που λέει ο moukoublen παραπάνω να ζητήσουμε συγγνώμη για την παρεξήγηση να πάμε όλοι σπίτια μας.
migf1 Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Με είδες να έχω κάνει quote τον κώδικά σου ? Εγώ σχολίασα ακριβώς αυτό που έχω κάνει quote. Η ερώτηση της SO που δίνει ο defacer και το μήνυμα που έδωσες εσύ δεν μιλάνε για A[N*M] αλλά για A[N][M] το οποίο είναι UB.Δε ξέρω που τα βρήκες αυτά, αλλά εγώ στο νήμα της C++ έδωσα κώδικα με i*COLS+j σχολιάζοντας πως είναι εναλλακτική πρόταση του 2D για να χρησιμοποιήσει κανείς μονοκόμματη μνήμη, ο defacer έγραψε πως αν το κάνεις access όπως έδειχνα βγάζει UB (δίνοντας 2 τελείως άσχετα links από κάτω) κι εσύ επικρότησες. Και εσύ είσαι ελεύθερος να το χρησιμοποιείς. Και εγώ όμως είμαι ελεύθερος να σχολιάζω ότι είναι λάθος κάθε φορά που το γράφεις. Το ότι χρησιμοποιείς κάτι επί πάμπολλα χρόνια και το ότι έχεις εμπειρία δεν είναι επιχειρήματα. Και register σε βλέπω να χρησιμοποιείς συχνά-πυκνά και να αφαιρείς const με cast σε έχω δει. Επειδή στη πράξη τα χρησιμοποιείς χρόνια να μην πω ότι είναι λάθος και μπορεί να οδηγήσουν σε προβλήματα ? Επί πάμπολλα χρόνια σε DOS γράφονταν προγράμματα που έθεταν ακέραιες τιμές σε δείκτες και όλα έπαιζαν τζάμι. Αφού έπαιζε τόσα χρόνια θα είναι καλή πρακτική.Α ώστε είναι και λάθος το register, όχι δηλαδή απλώς περιττό στους mainstream compilers αλλά και λάθος. Μάλιστα! 1. http://books.google.gr/books?id=mM58oD4LATUC&pg=PA228&lpg=PA228v=onepage&q&f=false 2. http://gustedt.wordpress.com/2010/08/17/a-common-misconsception-the-register-keyword/ & https://gustedt.wordpress.com/2012/08/17/named-constants/ (σχετικο-άσχετο, αλλά άκρως ενδιαφέρον) 3. Λέω να κάνεις πρόταση στο committee να το αφαιρέσουν τελείως από την γλώσσα, μιας και είναι λάθος, ή έστω να μη λένε πως είναι implementation defined αλλά πως είναι λάθος να το χρησιμοποιείς σε frequently accessed vars, και να το έχεις μόνο για non-referenced objects... C99, 6.7.1. A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined.101) 101) The implementation may treat any register declaration simply as an auto declaration. However, whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary & operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1). Thus, the only operator that can be applied to an array declared with storage-class specifier register is sizeof. ... Σχετικά με το ότι με έχεις δει να κάνω cast const char * σε char *, θα συνεχίσω να το κάνω μιας και κάτι σαν το παρακάτω ... char *s_puts( const char *s ) { const char *cp = s; if ( !s ) return NULL; while (*cp) putchar( *cp++ ); putchar('\n'); return s; } int main( void ) { const char s[] = "1234"; s_puts( s ); exit(0); } ανάλογα τον compiler ή θα σου βγάλει warning, ή θα σε σταματήσει τελείως. Σε πλήρη αντίθεση δηλαδή με το... char *s_puts( const char *s ) { char *cp = (char *)s; if ( !s ) return NULL; while (*cp) putchar( *cp++ ); putchar('\n'); return (char *)s; } int main( void ) { const char s[] = "1234"; s_puts( s ); } που γίνεται απροβλημάτιστα compiled παντού, δεν πειράζει τα περιεχόμενα του s και δίνει σαφές hint στην υπογραφή της συνάρτησης πως δεν τα πειράζει, μιας και ο κώδικας της συνάρτησης δεν είναι καθόλου σίγουρο πως θα είναι διαθέσιμος. Αν με έχεις δει να το χρησιμοποιώ αλλιώς, πολύ θα ήθελα να μου δείξεις που (κι αν όντως έχω πειράξει περιεχόμενα του const *s, πολύ ευχαρίστως να το διορθώσω). Και τα επιχειρήματα για το ποιος είναι ο imitheos και ο defacer είναι μπούρδες. Ο ίδιος ο DMR να αναστηθεί και να έρθει να σου το πει, δεν πρόκειται να βγεις από το μυαλό σου. Επειδή λοιπόν εγώ δεν έχω 30 χρόνια εμπειρίας και δεν έχω ασχοληθεί με σοβαρά πρότζεκτς, ας πάω να κάνω τις ποταπές δουλειές μου αντί να χάνω χρόνο εδώ.Κάνε ότι νομίζεις, δικό σου ο χρόνος δική σου και η ευχέρεια στην διαχείρισή του. @Erevis: Ακόμα ένα θύμα που πιστεύει πως οι ισοδυναμίες (και όχι ισότητες) είναι απλώς διακοσμητικά στοιχεία in the real world: http://www.insomnia.gr/topic/437533-%CE%B5%CF%81%CF%89%CF%84%CE%AE%CF%83%CE%B5%CE%B9%CF%82-%CE%B3%CE%B9%CE%B1-c/page-68?do=findComment&comment=5067585
defacer Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Άντε μπράβο! Δώσε το σωστό το link το πρόστυχο να μαλώνουμε σαν άνθρωποι! Καλα ρε συ τώρα, αλήθεια; Δίνεις κώδικα που επειδή παράγει το αποτέλεσμα που περιμένεις αυτό αποδεικνύει "του λόγου το αληθές" πως δεν είναι UB?!?!?!? Αναρωτιέμαι πώς είναι η αίσθηση του να σε διορθώνει ο StarLight και να χει και δίκιο...
migf1 Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Άντε μπράβο! Δώσε το σωστό το link το πρόστυχο να μαλώνουμε σαν άνθρωποι! Καλα ρε συ τώρα, αλήθεια; Δίνεις κώδικα που επειδή παράγει το αποτέλεσμα που περιμένεις αυτό αποδεικνύει "του λόγου το αληθές" πως δεν είναι UB?!?!?!? Αναρωτιέμαι πώς είναι η αίσθηση του να σε διορθώνει ο StarLight και να χει και δίκιο... Δεν ρωτάς καλύτερα τον Αnanda Gunawardena στο Carnegie Mellon University? Πιθανότατα θα έχει πολύ μεγαλύτερη υπομονή από εμένα. Μπορείς επίσης να ρωτήσεις στο Nadeau Sogtware Consulting γιατί προμοτάρουν τις θεωρητικά UB ως τις ταχύτερες τεχνικές. Αλλιώς, ψάξε βρες κανέναν dev π.χ. από το Game Developing sector, και ρώτα τον γιατί χρησιμοποιούν θωρητικά UB του προτύπου στους κώδικές τους. ΥΓ. Αναρωτιέμαι πως είναι να μην έχεις γράψει ποτέ στη ζωή σου κώδικα για πράγματα που αρέσκεσαι να δασκαλεύεις και να κοντράρεσαι, με μοναδικό σου "χαρτί" τη θεωρία και το google.
defacer Δημοσ. 14 Μαΐου 2013 Δημοσ. 14 Μαΐου 2013 Ρώτησα στο Nadeau Sogtware Consulting (sic), το οποίο υποθέτω βρήκες όχι από το google αλλά επειδή έχεις επαγγελματικές σχέσεις μαζί τους, και δες τι μου είπαν: All of these methods have been seen in "hand optimized" code, even though some of them may be dubious. Όπως είχα γράψει σε προηγούμενο post που έσβησα, αλλά τώρα αισθάνομαι ότι μπορώ να επαναφέρω, στην αρχή το να δίνεις ο ίδιος links που σε διαψεύδουν ήταν αστείο. Τώρα μένει μόνο το wtf. Φυσικά αυτά δεν έχουν και πολλή σημασία. Η ένστασή μας ήταν ότι αυτό είναι UB, κάτι που το ένα από τα 2 link που έδωσες (αυτό δηλαδή που δουλεύει) δεν ακουμπάει καν (προφανώς, άλλος είναι ο σκοπός της σελίδας). Κλασικό trolling με links που πραγματεύονται πράγματα παντελώς άσχετα μ' αυτά που συζητάμε και πλήρη απουσία απάντησης στα ερωτήματα που θέτουμε. BTW: το "προμοτάρουν τις θεωρητικά UB ως ταχύτερες τεχνικές" είναι ο τρόπος σου να παραδεχτείς ότι όντως έχουμε δίκιο αλλά μη το παίρνουμε και πάνω μας γιατί δε ξέρουμε από ταχύτερες τεχνικές; Edit: βλέπω έκανες edit οπότε το παραπάνω quote δεν είναι ακριβές πλέον. Οπότε ας το συμπληρώσω με το εξής: Αν ψάξω και βρω game developer που υποθετικά όντως το κάνει αυτό (άσχετα που πρακτικά δε θα το κάνει, μιας και αν πιστέψουμε το link που ο ίδιος έδωσες το ταχύτερο είναι allocation και διαχείριση σαν 1d -- αλήθεια, τα διαβάζεις εσύ τα links που ποστάρεις?), ξέρεις τι θα μου απαντήσει αν σέβεται τον εαυτό του; Ότι ναι το καταλαβαίνει πως είναι UB αλλά το κάνει γιατί δουλέυει στα μηχανήματα των πελατών του και στο τέλος της ημέρας αυτό είναι που μετράει. Μακάρι να μπορούσες να κάνεις και συ το ίδιο.
Προτεινόμενες αναρτήσεις