vim
Οι μεταγλωττιστές βρίσκουν τα συντακτικά λάθη στα προγράμματά μας. Δυστυχώς, στην Πληροφορική υπάρχει κάτι σαν θεώρημα, που λέει ότι δεν θα κατασκευαστεί ποτέ ένας μεταγλωττιστής που θα βρίσκει λογικά λάθη. Ωστόσο υπάρχουν τρόποι να πολεμήσουμε τα σφάλματα (bugs) ενός προγράμματός μας, να κάνουμε δηλαδή αποσφαλμάτωση (debugging). Οι δύο παρακάτω υποενότητες αφορούν τις γλώσσες προγραμματισμού C και C++.
assert
-ionsassert()
του assert.h
. Π.χ. έστω η παρακάτω συνάρτηση:
int get_value (int array[], int i) { return array[i]; }Η συνάρτηση είναι απλή και φαίνεται να κάνει μια χαρά τη δουλειά της ― επιστρέφει το
i
-οστό στοιχείο του πίνακα array
. Όμως για να προλάβουμε τυχόν segmentation fault εν τη γενέσει τους, λόγω κακής κλήσης της συνάρτησης, καλό είναι να ξαναγράψουμε το παραπάνω, εφόσον μιλάμε για τη γλώσσα C, ως εξής:
#include <assert.h> int get_value (int array[], int i) { assert(i >= 0); return array[i]; }Αν παραβιαστεί η συνθήκη της
assert()
, το πρόγραμμα τερματίζει άμεσα, τυπώνοντας και τη γραμμή του πηγαίου αρχείου στην οποία απέτυχε η assertion. Περισσότερες πληροφορίες υπάρχουν στην ενότητα Β6 του Παραρτήματος Β του βιβλίου των Kernighan και Ritchie «Η Γλώσσα Προγραμματισμού C». Στη C++ αντί για την assert()
, καλό είναι να χρησιμοποιούμε εξαιρέσεις.
gcc
/g++
gcc
και g++
. Για περισσότερες πληροφορίες man gcc
ή info gcc
.
-pedantic
Εξασφάλιση ISO συμβατότητας του κώδικα
-Wall
Ενεργοποίηση πολλών προειδοποιήσεων. Μάλιστα αν μπει μαζί με την -O
εμφανίζει προειδοποίηση όταν υπάρχει κάποια μη αρχικοποιημένη μεταβλητή.-O
, η οποία κάνει βελτιστοποίηση, καλό είναι να μην χρησιμοποιείται μαζί τη -g3
-W
Ακόμα περισσότερες προειδοποιήσεις
-Wshadow
Για να μην υπάρχουν συγχύσεις αναφορικά με την εμβέλεια των μεταβλητών, τυπώνεται προειδοποίηση όταν π.χ. μεταβλητές εσωτερικών block σκιάζουν καθολικές μεταβλητές
-s
(το `s
' προέρχεται από το `s
trip') απογυμνώνει το εκτελέσιμο από πληροφορίες αποσφαλμάτωσης και έτσι το αρχείο αυτό γίνεται πιο μικρό. Εξυπακούεται ότι η -s
δεν θα πρέπει να χρησιμοποιείται μαζί με τις παραμέτρους αποσφαλμάτωσης (όπως η -g3
).
gdb
Αναλυτικές οδηγίες για τη χρήση του gdb
υπάρχουν στο εγχειρίδιο χρήσης του (man gdb
ή info gdb
), καθώς και στην Ενότητα 3 του Unix Programming Tools. Εδώ θα αναφερθούν εν συντομία κάποιες οδηγίες.
Έστω ότι θέλουμε να αποσφαλματώσουμε ένα αρχείο πηγαίου κώδικα test.c
. Τότε το μεταγλωττίζουμε με την παράμετρο -g3
(ή -g
):
gcc -g3 -o test test.c
Αντί για gcc
μπορούμε να έχουμε και τον g++
, αν μιλάμε για κώδικα C++. Η διαδικασία παραμένει ακριβώς η ίδια.
Έπειτα ξεκινάμε τον αποσφαλματωτή:
gdb test
Θα εμφανιστεί μια γραμμή εντολών. Τώρα μπορούμε να ορίσουμε κάποια breakpoints, δηλαδή κάποια σημεία στα οποία θέλουμε να σταματήσει η εκτέλεση του προγράμματός μας. Με την εντολή
b main
υποδεικνύουμε να σταματήσει το πρόγραμμα, όταν ξεκινήσει η main
. Αντί της main
, μπορούμε να βάλουμε οποιοδήποτε όνομα συνάρτησης. (Μάλιστα αν πατήσουμε Tab, καθώς γράφουμε το όνομα μιας συνάρτησης, γίνεται συνήθως auto-complete.) Με την
b 10
δημιουργείται ένα breakpoint στη γραμμή 10 του αρχείου πηγαίου κώδικα. Αν θέλουμε να βάλουμε ένα breakpoint σε συγκεκριμένη γραμμή, συγκεκριμένου αρχείου, γράφουμε b αρχείο:γραμμή
. Είναι σημαντικό να βάλουμε τουλάχιστον ένα breakpoint, γιατί αν δεν υπάρχει κανένα, το πρόγραμμα θα εκτελεστεί χωρίς να σταματήσει πουθενά. Επίσης, τα breakpoints σε γραμμές που είναι κενές, ή περιέχουν μόνο σχόλια ή δηλώσεις (και όχι εντολές) δεν δουλεύουν. Για να τρέξουμε το πρόγραμμα, γράφουμε
r
ή run
. Μετά την r
μπορούμε να γράψουμε τα ορίσματα της γραμμής εντολών για το πρόγραμμά μας, εφόσον υπάρχουν. Με τη
n
ή next
, εκτελούμε την εμφανιζόμενη εντολή. Αν η εμφανιζόμενη εντολή περιέχει κλήση συνάρτησης, αντί για n
μπορούμε να γράψουμε
s
που είναι το λεγόμενο step
, δηλαδή «μπες μέσα στη συνάρτηση». Αν δεν κάνουμε step
και γράψουμε n
, η συνάρτηση θα εκτελεστεί, θα επιστρέψει και θα συνεχίσουμε με την επόμενη γραμμή. Σχετικές εντολές είναι η
u
ή until
, με την οποία τελειώνουμε τους βρόχους, καθώς και η
f
ή finish
, με την οποία τελειώνουμε με την εκτέλεση της τρέχουσας συνάρτησης (δηλαδή της συνάρτησης μέσα στην οποία βρισκόμαστε).
Συνοπτικά με τις n
, s
, u
και f
προχωράμε στο πρόγραμμά μας, με διαφορετικούς όμως τρόπους.
Η σημαντικότερη εντολή πάντως είναι η print
, αφού εμφανίζει τις τρέχουσες τιμές των μεταβλητών. Π.χ. μπορούμε να γράψουμε
p Y[i]
Μπορούμε επίσης να τυπώσουμε οποιαδήποτε έκφραση της C (ή της C++). Π.χ.
p (1+x*5)/2.0
ακόμα και
p 1+1
Αν θέλουμε μετά από κάποιο breakpoint που συνέβη, να συνεχίσει το πρόγραμμα κανονικά γράφουμε
c
ή continue
.
Αξίζει να σημειωθεί ότι σε μερικά συστήματα είναι διαθέσιμη η εφαρμογή ddd
, η οποία είναι μια εύχρηστη γραφική απεικόνιση του gdb
. Μία ακόμα βολική εκδοχή του gdb
είναι ο gdbtui
. Ο gdbtui
υπάρχει μαζί σχεδόν με όλες τις εκδόσεις του gdb
και χρησιμοποιείται ακριβώς όπως ο τελευταίος. (Δεν υπάρχει στα μηχανήματα Sun του Τμήματος.) Τέλος, ένας άλλος αποσφαλματωτής, που εστιάζει στον έλεγχο της διαχείρισης μνήμης, είναι το valgrind
, το οποίο είναι όμως διαθέσιμο μόνο για Linux. Κάποιες οδηγίες χρήσης του υπάρχουν εδώ. Φυσικά, όπου αναφέρεται ο g++
, μπορούμε κάλλιστα να χρησιμοποιήσουμε τον gcc
, εφόσον μεταγλωττίζουμε αρχεία *.c
.
-g3
. Π.χ. gcc -g3 -o test test.c
gcc
, θα τρέξουμε τον g++
.)
gdb
. Π.χ. gdb test
r
r
Program recieved signal SIGSEGV, Segmentation fault. 0x110cc in flood (x=9877, mac=0x23750, row=355, column=419) at test.c:75 75 if(mac[row+1][column]!=FLOODED)Το «
at test.c:75
» στη 2η γραμμή του παραπάνω μηνύματος σημαίνει ότι το segmentation fault συνέβη στη γραμμή 75 του αρχείου test.c
― μάλιστα η συγκεκριμένη γραμμή 75 τυπώνεται στην 3η γραμμή του μηνύματος. Στη 2η γραμμή του μηνύματος υπάρχει επίσης και το όνομα της συνάρτησης, μέσα στην οποία βρισκόταν το πρόγραμμα όταν συνέβη το μοιραίο (εδώ είναι η flood
), καθώς και οι τιμές των ορισμάτων της (εδώ x=9877, mac=0x23750, row=355, column=419
). Όταν ένας αριθμός ξεκινάει με `0x
' σημαίνει ότι είναι στο δεκαεξαδικό σύστημα και συνήθως αναφέρεται σε δείκτη (pointer). Το `0x0
' αντιστοιχεί στον δείκτη `NULL
'.
bt
κάνουμε BackTrace. Δηλαδή εμφανίζουμε τη στοίβα των συναρτήσεων, που θα πει ότι εκτός από την τελευταία συνάρτηση (που φάνηκε στο προηγούμενο βήμα), θα τυπωθεί το όνομα της συνάρτησης που κάλεσε την τελευταία συνάρτηση, καθώς και το όνομα της συνάρτησης που κάλεσε την προτελευταία συνάρτησης κ.ο.κ. Με την εντολή bt full
, εκτός από τις τιμές των παραμέτρων των συναρτήσεων στη στοίβα, τυπώνονται και οι τιμές των αυτόματων μεταβλητών τους.
vim
vim
υπάρχουν εδώ. Η έκδοση του προγράμματος για Windows υπάρχει εδώ. Παρακάτω θα παρουσιαστούν μερικές λίγο πιο προχωρημένες δυνατότητές του.
=
' στοιχίζουμε την τρέχουσα γραμμή. Πατώντας `gg=G
' στοιχίζουμε όλο το αρχείο ― με αυτόν τον τρόπο μπορούμε εύκολα να στοιχίσουμε τον κώδικα σε ένα αρχείο *.c
.
~
', αν το γράμμα είναι κεφαλαίο, γίνεται μικρό και αντίστροφα.
J
' (κεφαλαίο) ενώνουμε την τρέχουσα γραμμή με την αμέσως επόμενή της (αν φυσικά υπάρχει).
>>
' στοιχίζουμε την τρέχουσα γραμμή δεξιότερα (δηλαδή βάζουμε ένα Tab στην αρχή της) και αντίστροφα με το `<<
'
vim
και πληκτρολογώντας compl
Ctrl+P εμφανίζεται ολόκληρη η λέξη complete
.
x
' για διαγραφή, ή, το καλύτερο,
I
' (κεφαλαίο)
//
' όσες συνεχόμενες
γραμμές κώδικα C++ επιθυμούμε, εύκολα και γρήγορα!
vim
στα Windows, τότε μπορούμε στον Windows Explorer να επιλέξουμε δύο ως τέσσερα αρχεία, να κάνουμε δεξί κλικ σε αυτά και να επιλέξουμε Diff with Vim. Με αυτόν τον τρόπο μπορούμε να δούμε τις διαφορές τους. Στην κατάσταση γραμμής εντολών (σε οποιοδήποτε λειτουργικό), γράφουμε vim -d λίστα_αρχείων
για να πάρουμε το ίδιο αποτέλεσμα. Αντί για vim
μπορούμε να γράψουμε και gvim
.
:
') h word
Ctrl+D εμφανίζονται όλα τα θέματα βοήθειας που σχετίζονται με το word
. Γράφοντας h topic
και πατώντας Enter, εμφανίζεται (αν υπάρχει) η βοήθεια για το topic
.
vim
, μπορούμε να τις περάσουμε στο αρχείο .vimrc
στον αρχικό μας κατάλογο στο Unix, ή στο αρχείο _vimrc
στον κατάλογο όπου έχει εγκατασταθεί το vim
στα Windows. Για περισσότερες πληροφορίες σχετικά με μία επιλογή, τρέξτε στο vim
την εντολή h επιλογή
set ignorecase
Κατά την αναζήτηση να μην διακρίνονται τα πεζά από τα κεφαλαία γράμματα.set noignorecase
, είτε στην έκφραση που αναζητούμε, να βάλουμε οπουδήποτε το `\C
', δηλαδή να γράψουμε π.χ./αναζ\C
set incsearch
Για αναζήτηση πριν ακόμα γράψουμε ολόκληρη τη λέξη που ψάχνουμε στο κείμενο
set cindent
Για να στοιχίζεται αυτόματα ο κώδικας C κατά τη συγγραφή του. (Παρεμφερής είναι και η επιλογή set autoindent
)
set showmatch
Μόλις γράφουμε ένα (
, {
ή [
, αυτό γίνεται κόκκινο μέχρι να γράψουμε το ταίρι του. Όταν το γράψουμε, ο δρομέας γυρνάει για λίγο στο προηγούμενο ταίρι και επανέρχεται
set showcmd
Προβολή μη ολοκληρωμένων εντολών
set number
Εμφάνιση αριθμών γραμμής
set ruler
Προβολή θέσης δρομέα
set wildmenu
Όταν είμαστε σε command mode και πατήσουμε Tab για αυτόματη συμπλήρωση εντολής, εμφανίζονται όλες οι δυνατές επιλογές
vim
στο Unix, έχουμε τη δυνατότητα να μεταφέρουμε τον δρομέα πάνω από έναν αριθμό και, πατώντας Ctrl-A ή Ctrl-X, να τον αυξήσουμε ή να τον μειώσουμε κατά 1 αντίστοιχα. Αν θέλουμε να αυξήσουμε τον αριθμό κατά k, απλά πληκτρολογούμε k Ctrl-A. Στα Windows θα πρέπει να εκτελέσουμε τις εντολές noremap <C-kPlus> <C-A>
και noremap <C-kMinus> <C-X>
. Έτσι, αντί για τους συνδυασμούς πλήκτρων Ctrl-A και Ctrl-X, θα μπορούμε να χρησιμοποιούμε τους αντίστοιχους Ctrl-(το + του NumPad) και Ctrl-(το - του NumPad).