Συμφωνώ με τα τελευταία σχόλια του Παναγιώτη.
Πριν από 2 χρόνια είχα μια μακροσκελή κουβέντα με τον Σπινέλλη.
Το θέμα μας ήταν το "ποιό ποσοστό του κώδικα είναι error handling" και αν μπορούν να φτιαχτούν εργαλεία metrics που να το μετράνε.
Η δική του εκτίμηση ήταν ότι για business critical συστήματα ήταν minimum 30%, και για mission critical (λειτουργικά, κλπ) περίπου 40%.
Εγώ, με βάση την προσωπική μου εμπειρία, δηλαδή το πώς γράφω κώδικα και πώς βάζω άλλους να γράφουν κώδικα, ήταν 40% και 50% αντίστοιχα.
Είναι εξαιρετικά εύκολο να γράψει κάποιος κώδικα που να δουλεύει σωστά, όταν ΟΛΑ πάνε καλά.
Το αγγούρι είναι όταν τα πράγματα δεν πάνε καλά, και υπάρχουν χιλιάδες τρόποι να μην πάνε καλά.
Για εμάς που είμαστε "παλιοί" τα exceptions είναι πολύ απλή ιστορία.
Υπήρχαν από την εποχή του DOS και Windows 3.1. Απλά setjmp και longjump και ήσουν έτοιμος.
Η χρήση τους υπερσπάνια, όπως π.χ. σε compiler γραμμένο σε C++ που κάνει την λεγόμενη αναδρομική κατάβαση.
Βέβαια δεν έκανε stack cleanup, έπρεπε να φροντίζω να κρατάω όλα τα objects κάπου, ώστε αν σκάσει "exception" να κάνω cleanup μόνος μου.
Σιγά το πράγμα.
Μετά τα NT βάλανε το SEH (Structured Exception Handling), το οποίο ήταν σε επίπεδο λειτουργικού, μαζί με finally, και δούλευε και σε kernel mode.
Πάλι, δεν είχε object cleanup. No big deal. Υπάρχουν εκατομμύρια γραμμες κώδικα που δεν χρησιμοποιούν objects.
Μετά τα έβαλε και η C++, ώστε κατά το stack unwinding να γίνονται cleanup τα local object (on stack), και μάλιστα επιτρέπει και μίξη SEH και C++ exceptions.
Πρέπει να καταλάβετε κάτι βασικό. Τα exceptions δεν είναι τίποτα άλλο παρά ένα φρικαλέο GOTO, που διατρέχει δεκάδες functions, με πιθανώς άγνωστο προορισμό, μαζί με ολίγη από gabrage colletion.
Είχε γράψει ο Joel Spolsky παλιότερα πάνω στο θέμα, ότι μισεί τα exceptions, και κάπου είχα γράψει και εγώ ότι τα υπερμισώ.
Ο λόγος;;;;
H σωστή κατανόηση και σωστή χρήση των exceptions είναι κάτι που ΔΕΝ μπορεί να συλλάβει ο μέσος προγραμματιστής.
Απλά ΔΕΝ ΜΠΟΡΕΙ.
Εγώ ξέρω πώς να τα χρησιμοποιήσω σωστά, αλλά γράφω κώδικα 20 χρόνια, έχω γράψει άπειρο mission critical kernel mode κώδικα, άπειρο business critical C++ κώδικα και κατανοώ πώς πρέπει να χειριζόμαστε τα exceptions και τι πάει να πει error handling.
Ο μέσος προγραμματιστής απλά θα κάνει ένα exception spaghetti.
Για να το θέσω απλά: Exception και Error ΔΕΝ ΕΙΝΑΙ ΤΟ ΙΔΙΟ ΠΡΑΓΜΑ.
Το .ΝΕΤ και η Java δυστυχώς το έχουν κάνει να φαίνεται το ίδιο, αλλά ΔΕΝ είναι το ίδιο.
Exceptions are exceptional or unpredictable problems, errors are expected or predictable problems.
Τα errors μπορούν να γίνουν handle, τα πραγματικά exceptions σπανίως.
Δοκιμάζει το πρόγραμμά σου να κάνει login κάπου (μέχρι χτες έπαιζε) και σήμερα παίρνει authentication error.
Αυτό είναι error, δεν είναι exception. Εϊναι 100% προβλέψιμο ότι θα συμβεί.
Πας να διαβάσεις ένα αρχείο, και δεν έχεις access στο directory.
Ή φορτώνεις και πας να σώσεις ένα αρχείο και κάποιος το έχει κάνει read-only. Έχεις security permissions, αλλά το αρχείο είναι read-only.
Γράφεις/Διαβάζεις από ένα USB Stick και ο χρήστης το βγάζει και την κάνει για Μπαχάμες.
Είναι errors όχι exceptions. 100% προβλέψιμο ότι θα συμβούν.
Κάνει ο κώδικάς σου download και κόβεται το connection. Error, not exception.
Τι είναι exceptions;
Κάνεις ένα query στη βάση, άμεσα ή έμμεσα, και τρώει timeout ή connection lost (στο local lan).
Κάνεις insert/update στη βάση και τρώει ο DB Server ένα disk full.
Πας να επικοινωνήσεις με έναν host και τρώς host unreachable.
Τρώς memory access violation exception (SEH) γιατί πήγες στα χωράφια.
Τρως memory allocation failure (memory full). To handling του memory full έχει πολύ πλάκα, έχω ρίξει απίστευτα γέλια. Τι μπορεί να κάνει ένα πρόγραμμα όταν τα Windows δεν μπορούν ούτε καν να ανοίξουν ένα message box???
Δηλαδή, νομίζετε ότι τόσα χρόνια τα λειτουργικά (στο μεγαλύτερο ποσοστό του κώδικα) και οι device drivers γράφονται σε C μόνο και μόνο για το performance;;; Και η C++ έχει ουσιαστικά το ίδιο performance.
Στα Windows όμως απαγορεύεται η C++ σε kernel code. ΑΠΑΓΟΡΕΥΕΤΑΙ. Γιατί;
(1) Έναν σοβαρό προγραμματιστή η C τον εξαναγκάζει να κάνει σωστό και πλήρες error handling. Και τον διευκολύνει να γράψει κώδικα δομημένο σωστά, γιατί ΔΕΝ του δίνει την επικύνδινη δυνατότητα για φρικαλέα GOTO.
(2) Ο κώδικας C είναι 100% predictable ώς προς το control flow. Δεν υπάρχουν "κρυμμένοι" copy constructors, destructors, garbage collections, overloaded operators κλπ που κάνουν μαγικά πράγματα χωρίς να παίρνει χαμπάρι τίποτα ο προγραμματιστής. Το control flow στη C είναι 100% explicit.
Ας το αφήσουμε αυτό, όποιος διαφωνεί δικαιωμά του.
Στην επιλογή γλώσσας προγραμματισμού και πλατφόρμας επικρατεί φυσική επιλογή.
Όσοι γουστάρουν και κατανοούν τα πολύπλοκα, κατανοούν και γουστάρουν το error handling και το επαγγελματικό error reporting, είναι οργανομένοι και τακτοποιημένοι μέσα στο μυαλό τους, δεν έχουν κανένα πρόβλημα με τη C και τη C++. Και καταλήγουν στις αντίστοιχες δουλειές.
Κάποιος που είναι ΟΚ με τη C++, την VB.NET θα την βρει μάλλον αηδιαστική, γιατί είναι πολύ πιο χύμα.
Εγώ την βρίσκω αηδιαστική και για τον επιπλέον λόγο, ότι εξαιτίας της φυσικής επιλογής, αν κουμάνταρα ένα project VB.NET τότε ΜΑΛΛΟΝ θα περιστοιχιζόμουνα από μέτριους και χύμα προγραμματιστές. Απλό είναι. Εγώ αν έγραφα VB.NET ο κώδικάς μου θα ήταν ολόιδιος με τη C#. 40-50% error handling. Και θα δούλευαν όλα ρολόι. Αλλά οι άλλοι γύρω μου;;;
Συνεπώς, αν δεχτείτε την εκτίμηση του Σπινέλλη για 30-40% error handling code, και κοιτάξετε ξανά τον κώδικά σας, θα δείτε ότι ΔΕΝ φταίει η γλώσσα. Οι προγραμματιστές φταίνε. Αυτά τα παραμύθια ότι η γλώσσα σε προστατεύει από λάθη, είναι 90% ΜΥΘΟΣ.
Δηλαδή το πρόβλημα της C/C++ είναι ότι δεν σε προστατεύει επειδή δεν ελέγχει τα array bounds???
Εϊπαμε, φυσική επιλογή. Αν δεν μπορείς να γράψεις κώδικα που χειρίζεται ένα φουκαριάρικο array σωστά, τότε ΠΑΡΑΤΑ τη C/C++, δεν είναι για σένα, δεν κάνεις για τις δουλειές που απαιτούν C++.
Ή το πρόβλημα είναι τα memory leaks? Αν δεν μπορείς να χειριστείς σωστά το memory handling, τότε ΠΑΡΑΤΑ τη C/C++, δεν κάνεις για τις δουλειές που απαιτούν C++.
Και το .ΝΕΤ έχει memory leaks, κάντε ένα google search να ρίξετε γέλιο. Ο Μανωλιός έβαλε τη σκούφια του αλλιώς.
Έχω γράψει και εγώ μπόλικη VB6 στο παρελθόν. Και είχα γράψει και OnError Resume Next. Αλλά έλεγχα το τιμημένο error code, δεν συνέχιζα στην καλή χαρά.
Αν έβλεπες την VB6 που έγραφα θα φρικάριζες, ήταν τόσοι πολλοί οι έλεγχοι που γινόντουσαν και τόσο αναλυτικό το error reporting που όντως ήταν το 30-40% του κώδικα. Και όταν τον βλέπανε οι normal VB6 programmers της εταιρίας, πραγματικά "φρικάρανε" και με ρωτάγανε αν πράγματι χρειάζεται τόσο πολύ error checking και μήπως υπερβάλλω.
Τα συγκεκριμένα components εμπλεκόντουσαν στην αποστολή εντολών στο ΧΑΑ... μάλλον δεν υπερέβαλα. Και τόσα χρόνια ΠΟΤΕ δεν υπήρξε bug στις live εγκαταστάσεις.
Συνεπώς: ΔΕΝ φταίει η γλώσσα. ΦΤΑΕΙ ο προγραμματιστής.
End of Story
The fact that the program works is irrelevant.