Κατηγορίες λαθών

Ξεκίνησε από alkisg, 28 Μαρ 2020, 10:04:54 ΠΜ

« προηγούμενο - επόμενο »

alkisg

Πολλές φορές έχουμε συζητήσει τις κατηγορίες λαθών στο Στέκι, αλλά δεν έχουμε καταλήξει. Ξεκινάω μια προσπάθεια εμβάθυνσης, ώστε να συμφωνήσουμε τουλάχιστον στο επιστημονικό κομμάτι, και στη συνέχεια να προσπαθήσουμε να επεκταθούμε στην ερμηνεία του βιβλίου, ποια σημεία θεωρούνται γκρίζα, πώς θα πρέπει να τα διδάσκουμε/εξετάζουμε κλπ.

Θα ξεχωρίσω πρώτα τις κατηγορίες λαθών με βάση τα παρακάτω εργαλεία:

- Οι lexers κάνουν λεκτικό έλεγχο. Ανοικτά αλφαριθμητικά, άκυρα σύμβολα κλπ ανιχνεύονται εδώ. Για απλούστευση, στη ΓΛΩΣΣΑ αυτά τα έχουμε ενώσει με τα συντακτικά λάθη.
- Οι parsers κάνουν συντακτικό έλεγχο. "ΓΙΑ ι ΕΠΑΝΑΛΑΒΕ" ανιχνεύεται εδώ.
- Οι linters κάνουν στατική ανάλυση του κώδικα, με σκοπό να ανιχνεύσουν λογικά λάθη πριν ακόμα εκτελεστεί το πρόγραμμα. ΑΝ λοιπόν θεωρήσουμε ότι η ΓΛΩΣΣΑ περιλαμβάνει linter, η διαίρεση με το μηδέν, η προσπέλαση στοιχείων εκτός πίνακα κλπ θα μπορούσαν να ανιχνευτούν και πριν την εκτέλεση, ενώ κανονικά ανιχνεύονται κατά την εκτέλεση.
- Οι βιβλιοθήκες των γλωσσών προγραμματισμού και των λειτουργικών συστημάτων (runtime systems) εγείρουν τα λάθη χρόνου εκτέλεσης, και εμφανίζουν είτε warnings είτε προκαλούν αντικανονικό τερματισμό του προγράμματος, πριν το φυσιολογικό ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ.

Πάμε τώρα στους compilers / interpreters. Αυτοί στην "απλή" τους έκδοση περιλαμβάνουν μόνο lexers / parsers / runtime-systems.
Άρα αν ζητήσουμε η ΓΛΩΣΣΑ να υλοποιείται με "απλό" Διερμηνευτή, τότε τα περισσότερα "ασαφή σημεία" που συζητάμε, όπως η διαίρεση με το μηδέν ή η ΓΡΑΨΕ εντός συναρτήσεων, ΔΕΝ μπορούν να ανιχνευτούν πριν την εκτέλεση.
Όμως, όλοι οι μοντέρνοι compilers / interpreters είναι πολύ προχωρημένοι και περιλαμβάνουν και linters ή/και code optimizers. Σε αυτήν την περίπτωση, πολλά λάθη θα μπορούσαν να ανιχνευτούν και πριν την εκτέλεση. Όμως ΔΕΝ θα έπρεπε να τα αποκαλούμε "συντακτικά λάθη" για να μην μπλεχτούμε, αλλά να κάνουμε μια νέα κατηγορία λαθών γι' αυτά, "compiler warnings" ή "lintian λάθη" κλπ.

Για παράδειγμα, ο GNU compiler gcc περιλαμβάνει τις παρακάτω ενδιαφέρουσες επιλογές:

  • -fsyntax-only: μόνο απλός συντακτικός έλεγχος, καθόλου linting
  • -Wfatal-errors: τα warnings γίνονται λάθη και δεν προχωράνε σε εκτέλεση
  • -Wunused-variable: μεταβλητή δηλώθηκε αλλά δεν χρησιμοποιήθηκε
  • -Wuninitialized: μεταβλητή χρησιμοποιήθηκε χωρίς να αρχικοποιηθεί
  • -Warray-bounds: προσπέλαση στοιχείου πίνακα εκτός ορίων
  • -Wdiv-by-zero: προειδοποίηση για στατική διαίρεση με το μηδέν
Έτσι, υπάρχει η δυνατότητα το 1/0 να μην το καταλάβει καθόλου, ή να το καταλάβει και να θεωρηθεί fatal warning και να μην προχωρήσει σε εκτέλεση. ΔΕΝ υπάρχει όμως η δυνατότητα να καταλάβει το ΔΙΑΒΑΣΕ α, ΓΡΑΨΕ 1/α, και ο χρήστης να δώσει α=0, αυτό θα είναι πάντα σφάλμα χρόνου εκτέλεσης. Υπάρχει και η δυνατότητα μια μεταβλητή που δεν χρησιμοποιήθηκε να θεωρηθεί σφάλμα και να μην γίνεται εκτέλεση πριν διορθωθεί.

Προτείνω να αναφέρουμε ως συντακτικά λάθη, και να εξετάζουμε ως συντακτικά λάθη, μόνο αυτά που αντιστοιχούν στο "-fsyntax-only". Δηλαδή κανείς μας να μην αναφέρει το 1/0 ως συντακτικό λάθος.
Περαιτέρω, αν ζητήσουμε από το Διερμηνευτή να κάνει έλεγχο τύπου lint, και να ανιχνεύσει τέτοια λάθη πριν την εκτέλεση, ΠΑΛΙ να μην τα αναφέρουμε ως συντακτικά.
Για παράδειγμα, ο Διερμηνευτής κάνει κάποιους ελέγχους lint, π.χ. έχει επιλογή για το αν επιτρέπεται ή όχι η ΓΡΑΨΕ μέσα σε συναρτήσεις. Αυτό λοιπόν ανιχνεύεται πριν την εκτέλεση, άρα κάποιος θα μπορούσε να το πει "συντακτικό λάθος". Δεν παραβιάζεται όμως κάποιος συντακτικός κανόνας, αυτό το λάθος ανιχνεύεται κατά το linting / static code analysis, που είναι διαφορετικό πράγμα. Δεν έχει νόημα ούτε εμείς ούτε οι μαθητές να μπερδευτούμε με αυτό. Βλέποντας όλη τη σύγχιση που έχει δημιουργηθεί, ίσως θα ήταν καλύτερα να μην είχα βάλει καθόλου linting στο Διερμηνευτή.

Ένα ακόμα σημείο αντιπαραθέσεων είναι τα λάθη χρόνου εκτέλεσης, που είναι ταυτόσημα με τα "λάθη που προκαλούν αντικανονικό τερματισμό", αλλά δεν αναλύονται και πολύ καλά. Λάθη χρόνου εκτέλεσης λέμε τα warnings ή errors που εμφανίζει το runtime system. Η διαίρεση με το μηδέν θα προκαλέσει CPU interrupt το οποίο θα το χειριστεί η libc κλπ. Και μπορούν είτε να εμφανίσουν ένα warning "διαίρεση με το μηδέν, οκ, συνεχίζω", ή να σταματήσουν με "αντικανονικό τερματισμό" την εκτέλεση, είτε ακόμα να πάνε στο "onerror ... goto" που λέει το βιβλίο για την Basic, όπου γίνεται ο "χειρισμός του λάθους χρόνου εκτέλεσης", και έτσι αποφεύγεται ο αντικανονικός τερματισμός.
Εδώ για απλούστευση θα πρότεινα όλα τα λάθη χρόνου εκτέλεσης να θεωρήσουμε ότι προκαλούν τερματισμό και είναι εντελώς ισοδύναμα με τα "λάθη που προκαλούν αντικανονικό τερματισμό".
Προσοχή, ένα άπειρο loop δεν προκαλεί κανένα λάθος χρόνου εκτέλεσης, ούτε η CPU ούτε η libc κλπ δεν καταλαβαίνουν ότι κάτι πάει στραβά. Ο Διερμηνευτής εδώ πάλι πάει να κάνει τον έξυπνο και λέει "έχουν γίνει 100.000 επαναλήψεις, μήπως υπάρχει άπειρο loop;" αλλά δεν μπορούμε αυτό να το εντάξουμε στα λάθη εκτέλεσης.

Τελευταίο σημείο αντιπαραθέσεων είναι τα λογικά λάθη. Λογικά λάθη είναι όλα τα λάθη που έχουμε στον κώδικά μας, που αν μας τα επισημάνει κάποιος, θα σπεύσουμε να τα διορθώσουμε. Κανένα λογικό λάθος δεν πιάνεται κατά τον συντακτικό έλεγχο. Μερικά λογικά λάθη πιάνονται κατά τον lint έλεγχο. Μερικά λογικά λάθη προκαλούν λάθη χρόνου εκτέλεσης, ενώ άλλα όχι, οπότε τα παρατηρούμε μόνο επειδή το πρόγραμμα μερικές φορές δεν κάνει αυτά που θέλαμε.

Έτσι, παραθέτω εδώ μερικές "ζόρικες" ερωτήσεις/απαντήσεις, κι αν θέλετε ρωτήστε κι άλλες, να τις συγκεντρώσω εδώ, και από δίπλα μετά να γράψουμε αν η πλειοψηφία συμφωνεί ή όχι.

Τι λάθος είναι το 1/0;
Κανονικά χρόνου εκτέλεσης, αλλά μπορεί να βρεθεί και με static code analysis (lint). Δεν μπορεί όμως να θεωρηθεί συντακτικό.

Υπάρχουν λογικά λάθη που να μην προκαλούν λάθη χρόνου εκτέλεσης;
Ναι, για παράδειγμα ένα άπειρο loop.

Υπάρχουν λάθη χρόνου εκτέλεσης που να μην είναι λογικά;
Ναι, για παράδειγμα ΓΡΑΨΕ "Hello world" να βγάζει "σφάλμα, δεν βρέθηκε οθόνη (stdout)". Η επίλυσή του δεν αφορά τον κώδικά μας άρα δεν είναι λογικό λάθος (μας).

Τι λάθος είναι η ΓΡΑΨΕ εντός συναρτήσεων;
Με βάση τις γενικότερες επιστημονικές μας γνώσεις, θα θέλαμε να μην είναι λάθος. Με βάση το βιβλίο, είναι απλά κακή πρακτική. Με βάση την οδηγία του Υπουργείου, είναι λάθος χωρίς να αναφέρεται ο χρόνος που θα ανιχνευτεί. Με βάση το Διερμηνευτή, ΑΝ η σχετική επιλογή είναι ενεργοποιημένη (που είναι by default), είναι λάθος τύπου lint/static code analysis. Δεν υπάρχει κάποια ένδειξη πουθενά ώστε να θεωρηθεί συντακτικό ή χρόνου εκτέλεσης. Άρα στα πλαίσια της ΑΕΠΠ αυτή η ερώτηση είναι βαθύ γκρίζο.

ApoAntonis

Παράθεση από: alkisg στις 28 Μαρ 2020, 10:04:54 ΠΜ
Υπάρχουν λογικά λάθη που να μην προκαλούν λάθη χρόνου εκτέλεσης;
Ναι, για παράδειγμα ένα άπειρο loop.

Το έχω ξαναγράψει, ελπίζω να μην γίνομαι κουραστικός, τα infinite loops
κινούνται στο όριο της ύλης.

i <- 0
x <- 1
ΟΣΟ ( x > 0) ΕΠΑΝΑΛΑΒΕ
    i <- i + 1
    x <- x/2
ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ


ενώ αν ακολουθεί η εντολή
tmp <- 1/x


το λάθος είναι αχαρακτήριστο ... με αυτά που γνωρίζουμε.

Ακόμα μια απορία. Η δήλωση ακέραιας μεταβλητής ως πραγματική, συνιστά λάθος;

alkisg

Παράθεση από: ApoAntonis στις 29 Μαρ 2020, 11:35:07 ΠΜ
Το έχω ξαναγράψει, ελπίζω να μην γίνομαι κουραστικός, τα infinite loops κινούνται στο όριο της ύλης.

Για να μην μπλέξουμε τις συζητήσεις, εγώ έλεγα για infinite loops (ΟΣΟ ΑΛΗΘΗΣ ΕΠΑΝΑΛΑΒΕ).
Το παράδειγμά σου κυρίως είναι για την ακρίβεια των πραγματικών αριθμών. Το αν θα κάνει άπειρη επανάληψη ή όχι είναι η παρενέργεια, όχι ο πυρήνας του συγκεκριμένου παραδείγματος.

Αν υποθέσουμε ότι η ΓΛΩΣΣΑ έχει άπειρη ακρίβεια στους πραγματικούς, τότε έχουμε κάνει λάθος υπόθεση, αφού κανένας ψηφιακός υπολογιστής δεν μπορεί να χωρέσει ούτε μία "άπειρη" μεταβλητή. Το σωστό είναι να υποθέσουμε ότι η ΓΛΩΣΣΑ "έχει όσο μεγάλη ακρίβεια χρειαζόμαστε για την επίλυση του προβλήματος", αλλά αυτό δεν στέκει στο παράδειγμα που δίνεις, αφού προσπαθείς να βρεις τα όρια της ακρίβειας. Δηλαδή η κατάλληλη απάντηση είναι ότι το παράδειγμα είναι λάθος.

Παρ' όλα αυτά προχωράμε παρακάτω και δεχόμαστε ότι έχουμε "μια κάποια ακρίβεια", και πάμε να τρέξουμε το παράδειγμά σου. Εκεί λοιπόν θα γίνει "underflow" στην τελική x <- x/2, το οποίο το runtime-system μπορεί να το πιάσει, και επομένως θα έχουμε λάθος χρόνου εκτέλεσης.
Αν δεν πιάσει το "underflow" στο x/2 και το κάνει σιωπηλά 0, τότε θα έχουμε διαίρεση με το 0 στο tmp <- 1/x. Και πάλι δηλαδή λάθος χρόνου εκτέλεσης, αλλά φυσικά όχι επειδή έχει άπειρες επαναλήψεις, αλλά επειδή έφτασε τα όρια ακρίβειας των πραγματικών αριθμών.

Παράθεση από: ApoAntonis στις 29 Μαρ 2020, 11:35:07 ΠΜ
Ακόμα μια απορία. Η δήλωση ακέραιας μεταβλητής ως πραγματική, συνιστά λάθος;

Εάν εκεί που χρησιμοποιούμε τη μεταβλητή, μπαίνει και ακέραια και πραγματική (π.χ. σε ΔΙΑΒΑΣΕ, στο εσωτερικό της Τ_Ρ, ...), τότε δεν είναι λάθος.
Αν μπαίνει μόνο ακέραια (π.χ. ως τελεστέο των mod/div, ως δείκτη πίνακα), τότε είναι συντακτικό λάθος.

bugman

Τα λάθη τύπου lint θα μπορούσαν να λέγονταν ΑΝΑΛΥΤΙΚΑ ΛΑΘΗ. Οπότε αν υπάρχει αναλυση λαθών τότε υπάρχουν τα ανάλογα λάθη πριν την εκτέλεση, αλλιώς θα είναι επί της εκτέλεσης.

Τα σφάλματα επί της εκτέλεσης χωρίζονται σε αυτά που παγιδεύονται πχ σε μια on error και σε αυτά που προκαλούν απότομο τερματισμό (fatal error). Εκτός της παγίδευσης λαθών, υπάρχει και η έννοια της εκτροπής των εξαιρέσεων. Μια εξαίρεση στην ουσία είναι το λάθος το οποίο μια συγκεκριμένη  λειτουργία  το αναγνωρίζει ως δικό της, ώστε να γυρίσει μια προβλεπόμενη αναφορά προβλήματος. Πχ μια διαδικασία λαμβάνει τρεις τιμές και επιστρέφει δυο, το αποτέλεσμα και την αιτιολογία λάθους. Η αιτιολογία λάθους είναι το λάθος που βρίσκεται από τη διαδικασία, το προγραμματιζόμενο λάθος. Έτσι σε επόμενο βήμα μετά τη κλήση της διαδικασίας του παραδείγματος η πρώτη τιμή θα θεωρηθεί σωστή αν η τιμή της δεύτερης είναι έστω μηδέν. Αν δεν είναι μηδέν τότε βάσει του αριθμού το πρόγραμμα θα ενημερώσει για την αποτυχία της εκτέλεσης της διαδικασίας. Το τι θα γίνει μετά είναι θέμα προγράμματος.

Η ελεγχόμενη ροή εκτέλεσης σε περίπτωση σφάλματος μπορεί να θεωρηθεί σαν να υπάρχει λειτουργία εξαιρέσεων.
Το αντίθετο, ο μη ελεγχόμενος τερματισμός υποδηλώνει ότι σε επίπεδο κάτω από αυτό της εφαρμογής ή προγράμματος, έχει προκληθεί εξαίρεση που δεν σταμάτησε πρόγραμματιστικά  Αυτό είναι το σφάλμα χρόνου εκτέλεσης.

Πχ. Έχουμε ένα πρόγραμμα που τρέχει σωστά εδώ και καιρό και έστω ότι σε αυτό ανοίγουμε ένα αρχείο και καταχωρούμε νούμερα. Κάποια στιγμή το μέσο εγγραφής έχει γεμίσει. Δεν το ξέρουμε και τρέχουμε το πρόγραμμα. Πάει λοιπόν το πρόγραμμα να φτιάξει το αρχείο και η λειτουργία του συστήματος λέει ότι δεν μπορεί. Στο πρόγραμμα μας όμως δεν είχε συμπεριληφθεί αυτή η εξαίρεση οπότε συνεχίζει στην επόμενη εντολή να στείλει στο αρχείο τα στοιχεία. Εδώ το λειτουργικό στέλνει πάλι εξαίρεση ότι δεν κάνει τη δουλειά να γράψει τους αριθμούς. Το ερώτημα εδώ είναι. Θα πρέπει με κάποιο τρόπο να μάθουμε αν όντως γράφτηκαν τα στοιχεία; Ναι θα έπρεπε αν επεξεργαζόμασταν τις εξαιρέσεις. Δείτε ότι δεν τις λέω λάθη, γιατί το πρόγραμμα δεν έχει λάθος, και έχει πολλές φορές τρέξει σωστά. Λοιπόν κάπου το σύστημα πρέπει να σταματά το πρόγραμμα, ώστε να καταλάβουμε ότι υπάρχει πρόβλημα και δεν το έχουμε υπό έλεγχο. Έτσι όταν το λειτουργικό βγάζει μια εξαίρεση περιμένει να πάρει το οκ από το πρόγραμμα ότι ικανοποιήθηκε διαφορετικά τερματίζει το πρόγραμμα. Έτσι στο παράδειγμα με την αδυναμία δημιουργίας αρχείου και ταυτόχρονα την μη διεκπεραίωση της εξαίρεσης , χωρίς να στείλει η εφαρμογή μας το καθάρισμα του σφάλματος, έχουμε τερματισμό αντικανονικό.


George

Παράθεση από: alkisg στις 29 Μαρ 2020, 12:04:56 ΜΜ

Παρ' όλα αυτά προχωράμε παρακάτω και δεχόμαστε ότι έχουμε "μια κάποια ακρίβεια", και πάμε να τρέξουμε το παράδειγμά σου. Εκεί λοιπόν θα γίνει "underflow" στην τελική x <- x/2, το οποίο το runtime-system μπορεί να το πιάσει, και επομένως θα έχουμε λάθος χρόνου εκτέλεσης.


Δηλαδή αυτό είναι λάθος χρόνου εκτέλεσης

    i <- 0
   x <- 1
   ΟΣΟ ( x > 0) ΕΠΑΝΑΛΑΒΕ
       i <- i + 1
       x <- x/2
   ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

Ενώ αυτό είναι λογικό λάθος;
   i <- 0
   x <- 1
  ΟΣΟ ( x > 0) ΕΠΑΝΑΛΑΒΕ
       i <- x + 2
      Γράψε i
   ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ





alkisg

Το πρώτο είτε θα προκαλέσει λάθος χρόνου εκτέλεσης (underflow/div-by-zero/out-of-ram) είτε θα εκτελείται επ' άπειρο χωρίς κανένα εμφανές λάθος, ανάλογα με το runtime system που τρέχει.

Το δεύτερο ναι είναι λογικό λάθος γιατί δεν αντιστοιχεί σε επίλυση κάποιας συγκεκριμένης εκφώνησης, εντός της επανάληψης δεν αλλάζουν ούτε το x ούτε το i. Αποκλείεται δηλαδή να είναι αυτό που στόχευε να κάνει ο προγραμματιστής του.

Για το πρώτο δεν μπορούμε να πούμε ότι έχει λογικό λάθος, αφού κάνει ακριβώς αυτό που ήθελε ο προγραμματιστής του, προσπαθεί να φτάσει στα όρια της ακρίβειας των πραγματικών. Όμως αυτή η επιδίωξη έρχεται σε αντίθεση και ακυρώνει την υπόθεση ότι η "ΓΛΩΣΣΑ έχει όσο μεγάλη ακρίβεια χρειάζεται για την επίλυση του προβλήματος", οπότε για τη ΓΛΩΣΣΑ είναι λάθος παράδειγμα.

Προσοχή, υπάρχουν λάθη χρόνου εκτέλεσης που συγχρόνως είναι και λογικά λάθη. Τα λογικά λάθη μπορούν να εμφανιστούν είτε κατά το linting είτε ως λάθη χρόνου εκτέλεσης είτε καθόλου, οπότε τότε τα καταλαβαίνουμε μόνο αν το πρόγραμμα δεν κάνει αυτό που θέλαμε.

bugman

#6
Underflow δεν εχω δει ποτέ. Δεν υπάρχει ούτε σε flag στον επεξεργαστή. Οι αριθμοί double 80bit έχουν την infinite ως θετικό άπειρο και αρνητικό άπειρο. Επιπλέον αν κάποιος βάλει με κάποιο τρόπο κάποια bit μπορεί να σχηματίσει NaN δηλαδή Not a Number.
Η συνεχόμενη διαίρεση θα βγάλει το 0.

Παίζει το 1/2 να δίνει 1 αν έχουμε πριν την εκχώρηση ακέραια τιμή με σχολική ακρίβεια, όπου η μισή μονάδα γίνεται ολόκληρη. Έτσι το 1/2 θα δίνει 1 στην εκχώρηση  έτσι συνέχεια η τιμή το Χ θα είναι 1. (Αυτό μπορεί να γίνει πχ στην Μ2000 σε ακέραιες μεταβλητές που στην εκχώρηση τιμής γίνεται στρογγυλοποίηση στο 0.5)


Να προσθέσω εδώ ότι υπάρχουν και άλλες αναπαραστάσεις αριθμών όπου πχ το 0.2 γράφεται επακριβώς ως 0.2. Αυτοί είναι οι τύπου Decimal με 29 ψηφία όπου το σημείο των δεκαδικών μπορεί να πάει παντού βάσει ενός εσωτερικού εκθέτη στο 10. Στην ουσία έχουμε ακέραια τιμή 96bit.

alkisg

https://en.wikipedia.org/wiki/Arithmetic_underflow
"The occurrence of an underflow may set a ("sticky") status bit, raise an exception, at the hardware level generate an interrupt, or may cause some combination of these effects. "

Μην περιορίζεσαι στον επεξεργαστή που έχεις στο σπίτι και στο τι έχεις δει στα runtime systems που δοκίμασες.
Επιπρόσθετα, οι πράξεις μπορούν να τρέχουν σε software, όχι hardware, με τη βοήθεια βιβλιοθήκης. Υπάρχουν βιβλιοθήκες "άπειρης ακρίβειας", αυτές θα συνεχίσουν μέχρι να τελειώσει η RAM (το out-of-ram που έγραψα).

Δεν νομίζω όμως ότι χρειάζεται να επικεντρωθούμε στο "τι είδους runtime error μπορεί να βγάλει", το ζητούμενο είναι ότι είτε θα βγάλει runtime error είτε θα εκτελείται για πάντα.

alkisg

Χθες μια μαθήτρια με ρώτησε "Τελικά τι λάθος είναι το Χ/0; Στο σχολείο μας είπαν ότι είναι λογικό λάθος, ενώ στο φροντιστήριο ότι είναι λάθος χρόνου εκτέλεσης και ότι τα λογικά λάθη δεν προκαλούν διακοπή της εκτέλεσης".

...ελπίζω να μην πέσει στις Πανελλαδικές, θα δυσκολευτούμε να συμφωνήσουμε ότι το σωστό είναι "και τα δύο"...  :-[

din_os

Χμμ, έκανα το μάθημα πρόσφατα και δεν περίμενα να δώ εδώ τέτοια συζήτηση, σύμφωνα με τα 2 βιβλία αυτό που κατάλαβα είναι:
- Συντακτικό λάθος, ανακαλύπτεται πρίν την εκτέλεση.
- Λάθος κατά την εκτέλεση, με αποτέλεσμα να κάνει "crash" όπως λέει και το βιβλίο επειδή μια συσκευή δεν βρέθηκε, μια τιμή χρήστη το προκάλεσε
- Λογικό λάθος, δεν ανακαλύπτεται από τα παραπάνω, μόνο άνθρωπος μπορεί να τα βρεί, (ή ίσως ΑΙ αν το πάμε βαθιά)

Πρίν πάω στις ερωτήσεις να δείξω ένα λογικό λάθος π.χ. να έχουμε αλγόριθμο που να βρίσκει μέσο όρο και να κάνει λάθος πράξη π.χ. εδώ ξέχασε ο προγ/στης τις παρενθέσεις:

Διαβασε α, β
Γραψε 'Ο μέσος όρος είναι ',  α + β / 2

Σύμφωνα με αυτά λοιπόν οι ερωτήσεις (ταπεινή γνώμη):

Τι λάθος είναι το 1/0;
Κανονικά χρόνου εκτέλεσης, αλλά μπορεί να βρεθεί και με static code analysis (lint). Δεν μπορεί όμως να θεωρηθεί συντακτικό.
- Συμφωνώ

Υπάρχουν λογικά λάθη που να μην προκαλούν λάθη χρόνου εκτέλεσης;
Ναι

Υπάρχουν λάθη χρόνου εκτέλεσης που να μην είναι λογικά;
Ναι

Τι λάθος είναι η ΓΡΑΨΕ εντός συναρτήσεων;
Συντακτικό

alkisg

@din_os, οπότε η βασική διαφωνία είναι στην παρακάτω ερώτηση:
Υπάρχουν λογικά λάθη που ταυτόχρονα είναι και λάθη χρόνου εκτέλεσης;

Εκεί εσύ (και άλλοι) απαντάς "όχι".
Εγώ (και άλλοι) απαντώ:

Παράθεση από: alkisg στις 30 Μαρ 2020, 09:32:26 ΠΜ
Προσοχή, υπάρχουν λάθη χρόνου εκτέλεσης που συγχρόνως είναι και λογικά λάθη. Τα λογικά λάθη μπορούν να εμφανιστούν είτε κατά το linting είτε ως λάθη χρόνου εκτέλεσης είτε καθόλου, οπότε τότε τα καταλαβαίνουμε μόνο αν το πρόγραμμα δεν κάνει αυτό που θέλαμε.

Το ΓΡΑΨΕ χ/0 είναι λογικό λάθος γιατί αποκλείται να είναι αυτό που ήθελε να κάνει ο προγραμματιστής. Είναι δηλαδή πάνω από όλα λάθος λογικής. Αν του το υποδείξουμε, θα σπεύσει να το διορθώσει.
Δευτερευόντως, ορισμένοι compilers θα εμφανίσουν warning/error κατά τη φάση "linting" της μεταγλώττισης.
Δευτερευόντως, ορισμένα run time systems θα σταματήσουν την εκτέλεση του προγράμματος, προκαλώντας λάθος χρόνου εκτέλεσης.
Κάποια run time systems δεν θα σταματήσουν καν την εκτέλεση γι' αυτό το λογικό λάθος. Αν τρέξετε την εντολή document.write(1/0) σε Javascript, απλά θα τυπώσει "Infinity" στην οθόνη.

Δεν έχω δει κάπου το βιβλίο να αντιτίθεται στα παραπάνω, αλλά δεν τα εξηγεί και αναλυτικά.
Ίσως να βοηθούσαν και οι παρακάτω εναλλακτικές διατυπώσεις, όπου με bold αναφέρεται η πηγή των λαθών:

  • Συντακτικά λάθη είναι αυτά που εμφανίζει ο compiler.
  • Λάθη χρόνου εκτέλεσης είναι αυτά που εμφανίζει το runtime system, οι βιβλιοθήκες (όχι το ίδιο το πρόγραμμα). Μερικά λάθη χρόνου εκτέλεσης μπορεί να σταματήσουν την εκτέλεση, ενώ μερικά είναι απλά warnings.
  • Λογικά λάθη είναι αυτά όπου ο προγραμματιστής δεν έκανε αυτό που ήθελε. Τα λογικά λάθη μπορεί να προκαλέσουν λάθη χρόνου εκτέλεσης αλλά μπορεί και όχι.
Ίσως αναφέροντας την πηγή, να φανεί ότι δεν μοιράζουμε μια πίτα σε 3 κατηγορίες, αλλά υπάρχει αλληλεπικάλυψη. Λάθη που κάνει ο προγραμματιστής μπορεί να τα πιάσει το runtime system αλλά μπορεί και όχι.

din_os

Ααα τώρα κατάλαβα συγνώμη, λοιπόν πάμε πάλι:
- Το χ/0 μπορεί εύκολα να το "δεί" ένας συντάκτης οπότε θα μπορούσαμε να το πούμε και συντακτικό, είναι λίγο κακό παράδειγμα όμως, ποιός διαιρεί με το μηδέν σε κώδικα;
- Το
Διαβασε χ
Γραψε 5/χ
όπου χ μπορεί να είναι μηδέν είναι λάθος κατά την εκτέλεση (προκαλεί crash και φταίει τιμή χρήστη) δεν θεωρώ όμως ότι είναι και λογικό λάθος. Άν το πάμε έτσι όλα τα λάθη κατά την εκτέλεση είναι και λογικά ( ; ) [φταίει ο προγ/στης που δεν έβαλε try catch]
- Ο μόνος τρόπος να έχει νόημα η θεωρία για εξετάσεις είναι τα λογικά να μην προκαλούν crash έτσι ώστε να ξεχωρίζει.

Πρόσφατα διάβαζα ένα άρθρο για Visual Basic .NET που έκαναν pros/cons το να έχεις μια Global Try - Catch. Για σκέψου πώς αλλάζει αυτό την συζήτησή μας; Είναι σίγουρα καλό debate για προγραμματιστές αλλά τα παιδιά θέλουν κάτι πιο ξεκάθαρο και από τα λόγια του βιβλίου αυτό που τους είναι πιο ξεκάθαρο ίσως είναι ότι τα λογικά δεν προκαλούν crash.

Ταπεινή γνώμη :)

alkisg

Παράθεση από: din_os στις 03 Απρ 2020, 09:19:22 ΠΜ
Άν το πάμε έτσι όλα τα λάθη κατά την εκτέλεση είναι και λογικά ( ; ) [φταίει ο προγ/στης που δεν έβαλε try catch]

Λογικά λάθη είναι αυτά που έκανε ο προγραμματιστής. Να ένα παράδειγμα λάθους εκτέλεσης στο οποίο δεν φταίει ο προγραμματιστής, αφού η ΓΛΩΣΣΑ δεν έχει καν try/catch:

Παράθεση από: alkisg στις 28 Μαρ 2020, 10:04:54 ΠΜ
Υπάρχουν λάθη χρόνου εκτέλεσης που να μην είναι λογικά;
Ναι, για παράδειγμα ΓΡΑΨΕ "Hello world" να βγάζει "σφάλμα, δεν βρέθηκε οθόνη (stdout)". Η επίλυσή του δεν αφορά τον κώδικά μας άρα δεν είναι λογικό λάθος (μας).


Παράθεση από: din_os στις 03 Απρ 2020, 09:19:22 ΠΜ
- Ο μόνος τρόπος να έχει νόημα η θεωρία για εξετάσεις είναι τα λογικά να μην προκαλούν crash έτσι ώστε να ξεχωρίζει.

Δεν νομίζω ότι το βιβλίο λέει κάπου ότι οι 3 αυτές κατηγορίες ΔΕΝ αλληλεπικαλύπτονται. Αυτό είναι παρεξήγηση μεταξύ εμάς, των καθηγητών, και μπορούμε να τη λύσουμε.

Οι μαθητές ξέρουν τι σημαίνει αλληλεπικάλυψη. Στα πολλαπλάσια του 2 και του 3 υπάρχει αλληλεπικάλυψη, δεν πρέπει ντε και καλά να τα διδάξουμε σαν ανεξάρτητες κατηγορίες γιατί μας βολεύει όταν βγάζουμε θέματα.

Αν χρειαστούμε σχήμα, είχα ανεβάσει ένα εδώ:


  • Υπάρχουν λογικά που δεν είναι εκτέλεσης (κίτρινο)
  • Υπάρχουν λογικά που είναι και εκτέλεσης (πράσινο)
  • Υπάρχουν εκτέλεσης που δεν είναι λογικά (μπλε)

din_os

Ούτε λέει ότι αλληλεπικαλύπτονται όμως, γιατί να το κάνουμε πιο πολύπλοκο απ' ότι είναι;  Η απάντηση είναι επειδή μπορεί να πέσει ερώτηση. Η απάντηση σε αυτό είναι ότι τότε θα φταίνε αυτοί που ετοιμάζουν τις ερωτήσεις, πρέπει (και συνήθως το καταφέρνουν) να διαλέγουν ερωτήσεις ξεκάθαρες.

Η εμπειρία μου λέει να μην μπερδεύω τους μαθητές με πράγματα που είναι σπάνιο να προκύψουν. Οι μαθητές θέλουν κάτι ξεκάθαρο, κι'ας είναι λάθος.

Π.χ. το συμβάν με την μαθήτρια. Αν το φροντιστήριο είναι ξεκάθαρο και παρουσιάσει ορθά επιχειρήματα σε ένα context και το σχολείο παρουσιάσει επιχειρήματα για το αντίθετο στο ίδιο ή άλλο context, τότε μια καλή μαθήτρια θα κρίνει ποιο θα γράψει σύμφωνα με το context που θα παρουσιαστεί στις εξετάσεις. Άν όμως στο σχολείο/φροντιστήριο λέμε ξέρετε παιδάκια ή αυτό ή το άλλο ή το παρ-άλλο ανάλογα με το context, τότε (η εμπειρία μου πάντα λέει ότι) τα παιδιά νιώθουν ανασφάλεια και προκαλείται (ίσως περιττό) άγχος.

Ας πούμε ότι συμφωνούμε όλοι στο στέκι (και εγώ μαζί) ότι αλληλεπικαλύπτονται. Ποιός μου λέει ότι δεν θα πέσει ερώτηση που θα θεωρεί το αντίθετο; Δεν νομίζω λοιπόν ότι θα βοηθήσει σε κάτι να συμφωνήσουμε στο στέκι για ένα απο τα δύο. Αν θέλουν οι συγγραφείς ας το ξεκαθαρίσουν στην επόμενη έκδοση.

alkisg

Κανένας δεν μπορεί να εγγυηθεί ότι ο διορθωτής θα έχει την άποψη του σχολείου ή του φροντιστηρίου.
Επομένως αν διδάξεις κάτι "απλό κι ας είναι λάθος" δεν σημαίνει ότι θα εξασφαλίσεις τις σχετικές μονάδες για τους μαθητές σου.
Ίσα ίσα το "δίδαξα λάθος και έχασαν μονάδες" είναι πιο βαρύ από το "δίδαξα σωστά και έχασαν μονάδες".
Το καλύτερο για όλα τα αμφιλεγόμενα σημεία είναι να μην μπαίνουν σε θέματα Πανελλαδικών, και για όσα είναι σημαντικά, να διευκρινίζονται για επόμενες χρονιές.

Το Στέκι δεν έχει καμία επίσημη αξία. Παρ' όλα αυτά, μπαίνουν εδώ και καθηγητές σχολείων και φροντιστηρίων και βαθμολογητές και θεματοδότες.
Αν εντοπίσουμε προβληματικά σημεία, πιθανώς να βοηθήσουμε στο να μην μπουν τέτοια θέματα.
Αν ξεκαθαρίσουμε προβληματικά σημεία, πιθανώς να βοηθήσουμε να γίνουν διορθώσεις προς τη σωστή κατεύθυνση.
Μακάρι να είχε έναν επίσημο bug tracker ανά μάθημα το Υπουργείο και όλες αυτές οι συζητήσεις να γίνονταν κατευθείαν εκεί με κάποιον επίσημο να μας λέει την τελική ετυμηγορία. Δεν το έχουμε, αλλά αυτό δεν σημαίνει ότι τα φόρουμ είναι άχρηστα.