migf1 Δημοσ. 28 Νοεμβρίου 2011 Δημοσ. 28 Νοεμβρίου 2011 Δεν καταλαβαίνω τι εννοείς. O ts ρώτησε αν είναι σωστός ο κώδικάς του, του απάντησα πως σύμφωνα με την αναθεώρηση C99 είναι σωστός και αμφισβήτησες πως είναι σωστός επειδή χρησιμοποιεί πίνακα μεταβλητού μήκους. Το θεωρείς unsafe (και υπό προϋποθέσεις μπορεί να γίνει, όπως μυριάδες άλλα χαρακτηριστικά της C, αν δεν χρησιμοποιηθεί σωστά) αυτό όμως δεν σημαίνει πως είναι λάθος ο κώδικας του ts.
defacer Δημοσ. 30 Νοεμβρίου 2011 Δημοσ. 30 Νοεμβρίου 2011 @migf1: Έχεις απόλυτο δίκιο στο ότι το παλικάρι στην αρχή ρώτησε "αν είναι υποχρεωτική η malloc" και όπως λες δεν είναι. Η σωστή απάντηση όμως (προς τον ts) νομίζω πως είναι "κοίτα, πρέπει να καταλάβεις τη διαφορά ανάμεσα σε C90 και C99 και να ξέρεις τι compiler χρησιμοποιείς, επίσης αν μιλάμε για portability τότε malloc υποχρεωτικά". Απο κει και πέρα το παπί έχει κατ' εμέ δίκιο στο ότι dynamic allocation και stack δεν πάνε στην ίδια πρόταση. Κυρίως βασικά γιατί ανάλογα με το implementation μπορείς κάλλιστα να πέσεις σε λάκκους που σε καμία περίπτωση δεν αναφέρει τίποτα για όλα αυτά το standard (έτσι μου φαίνεται διαβάζοντας την παρ. 6.7.5.2, αφήνω μια μικρή πιθανότητα να μην έχω ψάξει σωστά). Επιπλέον υπάρχει και το θέμα ότι πλέον η συμπεριφορά δεν είναι consistent ανάμεσα σε διαφορετικούς compilers, κάτι που έρχεται σε ευθεία αντίθεση με ένα από τους βασικούς λόγους που επιλέγει κανείς να χρησιμοποιήσει C. Και όλα αυτά γιατί; Για να μη γράψει κανείς μία malloc; Δεν ξέρω τι σκέφτονταν όταν έβαλαν VLAs στη C99 (μήπως "οι compilers το κάνουν έτσι κι αλλιώς, ας πάμε με τα νερά τους"?), αλλά για μένα ήταν λάθος επιλογή και το feature δεν προσφέρει τίποτα (προσφέρει σε αυτούς που δεν έχουν βαθιά γνώση, αλλά δε νομίζω ότι είναι καλό να τους δίνεις κι άλλο σκοινί με το οποίο μπορούν να κρεμαστούν).
migf1 Δημοσ. 1 Δεκεμβρίου 2011 Δημοσ. 1 Δεκεμβρίου 2011 ... Κυρίως βασικά γιατί ανάλογα με το implementation μπορείς κάλλιστα να πέσεις σε λάκκους που σε καμία περίπτωση δεν αναφέρει τίποτα για όλα αυτά το standard (έτσι μου φαίνεται διαβάζοντας την παρ. 6.7.5.2, αφήνω μια μικρή πιθανότητα να μην έχω ψάξει σωστά). Επιπλέον υπάρχει και το θέμα ότι πλέον η συμπεριφορά δεν είναι consistent ανάμεσα σε διαφορετικούς compilers, κάτι που έρχεται σε ευθεία αντίθεση με ένα από τους βασικούς λόγους που επιλέγει κανείς να χρησιμοποιήσει C. Και όλα αυτά γιατί; Για να μη γράψει κανείς μία malloc; ... Προσωπικά δεν με χαλάει καθόλου η προσθήκη τους. Από τη στιγμή μάλιστα που παρέχεται η συμπεριφορά που περιγράφει το στάνταρ. επίσης δεν με χαλάει πως το υλοποιεί ο κάθε compiler. Άπαξ δηλαδή και είναι scoped όπως κάθε άλλη μεταβλητή, περιορίζονται σημαντικά και τα όποια ρίσκα... τα οποία έτσι κι αλλιώς δεν είναι καθόλου μεγάλα (στις περισσότερες πλατφόρμες το μέγεθος της stack περιορίζεται μονάχα από την ελεύθερη μνήμη του συστήματος). Ακόμα και σε loop να ορίσεις ένα VLA (όπως έγραψε ο παπι αν θυμάμαι σωστά) δεν υπάρχει πρόβλημα, γιατί δεν γίνεται allocate συνέχεια, μια μόνο φορά γίνεται allocate... και γίνεται μάλιστα αυτόματα deallocate μόλις βγει από το μπλοκ του loop. Άρα που είναι το πρόβλημα;
defacer Δημοσ. 1 Δεκεμβρίου 2011 Δημοσ. 1 Δεκεμβρίου 2011 Άρα που είναι το πρόβλημα; Προβλήματα μπορούν να υπάρξουν διάφορα, αλλά δε θα τα αναλύσω εδώ γιατί α) είναι πολύ technical, β) θα χρειαστεί πολύ χώρο και γ) (το βασικότερο) όλα τους ισχύουν και για fixed-length arrays όταν το παρακάνουμε με το μέγεθος του πίνακα. Επίσης ενδεχομένως να υπάρξει performance hit (μπορεί να οδηγήσει σε παραπάνω pointer derefs για τις μεταβλητές στο stack και επίσης με VLA δεν μπορείς να παραλείψεις τον stack frame pointer, που σημαίνει ότι ο compiler έχει ένα λιγότερο register της CPU για να κάνει τη δουλειά του) αλλά αυτά είναι τόσο ψιλά γράμματα που τα αναφέρω μόνο ακαδημαϊκά. Το κύριο πρόβλημά μου είναι πως όταν γράφεις "int arr[1000000]" τότε είναι προφανές ότι κάνεις βλακεία, ενώ όταν γράφεις "int arr[n]" δεν είναι το ίδιο προφανές ότι πρόκειται για κακή ιδέα. Θα χρειαστεί να κάνεις ελέγχους για το n (ποτέ δεν κάνουμε σημαντικά πράγματα που περιλαμβάνουν runtime υπολογισμούς χωρίς sanity checks έτσι?), αλλά δεν υπάρχει κανένας έλεγχος που μπορείς να κάνεις σε επίπεδο κώδικα για να καταλάβεις αν πίνακας X μεγέθους μπορεί να μπει στο stack. Με την malloc αντίθετα ξέρεις σίγουρα αν το allocation πέτυχε ή όχι.
migf1 Δημοσ. 1 Δεκεμβρίου 2011 Δημοσ. 1 Δεκεμβρίου 2011 Νομίζω διυλίζουμε τον κώνωπα (το οποία σε γενικές γραμμές κι εμένα μου αρέσει) αλλά στη συγκεκριμένη περίπτωση δεν νομίζω πως είναι χρήσιμο. Σε γενικές γραμμές η χρήση των VLA είναι εξίσου safe με την χρήση των static arrays, που με τη σειρά τους είναι έτσι κι αλλιώς πιο safe από οποιαδήποτε χειροκίνητη διαχείριση μνήμης με malloc() (άρα και free() ). Δεν νομίζω δηλαδή πως είναι χρήσιμο να αποκομίσει κάποιος διαβάζοντας το νήμα πως η χρήση των VLA είναι unsafe, ενώ του malloc() είναι safe.
defacer Δημοσ. 2 Δεκεμβρίου 2011 Δημοσ. 2 Δεκεμβρίου 2011 Νομίζω διυλίζουμε τον κώνωπα (το οποία σε γενικές γραμμές κι εμένα μου αρέσει) αλλά στη συγκεκριμένη περίπτωση δεν νομίζω πως είναι χρήσιμο. Σε γενικές γραμμές η χρήση των VLA είναι εξίσου safe με την χρήση των static arrays, που με τη σειρά τους είναι έτσι κι αλλιώς πιο safe από οποιαδήποτε χειροκίνητη διαχείριση μνήμης με malloc() (άρα και free() ). Δεν νομίζω δηλαδή πως είναι χρήσιμο να αποκομίσει κάποιος διαβάζοντας το νήμα πως η χρήση των VLA είναι unsafe, ενώ του malloc() είναι safe. Νόμιζα πως η παραπάνω απάντησή μου απαντά ικανοποιητικά σ' αυτό: με VLA δεν μπορείς να ξέρεις αν το πρόγραμμά σου θα κρασάρει ή όχι σε περίπτωση που τα μεγέθη του πίνακα ξεφύγουν (σε static array θα κρασάρει επιτόπου και στα μούτρα σου αν το κάνεις αυτό οπότε αναγκαστικά θα περιορίσεις τις ορέξεις σου). Με malloc όμως μπορείς να δεις ότι το allocation απέτυχε και να κινηθείς ανάλογα. Δεν θα έλεγα λοιπόν ότι οι VLA είναι "unsafe", θα έλεγα όμως "not as robust". Φυσικά για το συνηθισμένο επίπεδο ερωτήσεων του insomnia δε μπορείς να έχεις απαιτήσεις για έλεγχο επιστρεφόμενης τιμής της malloc οπότε δέχομαι τους VLA σαν "κάνε αυτό και μη μ' ενοχλείς άλλο" απάντηση. Αλλά για "σοβαρό" development πιστεύω ότι δεν τίθεται καν ερώτημα. Τέλος, με VLA κινδυνεύεις να πας σε άλλον compiler και να φας πόρτα, οπότε αν μπορείς να μάθεις μία προσέγγιση σε κάποιον αρχάριο ποιά θα του μάθεις;
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα